Creating Child Components in Vue Using Typescript

After using Vue for some time, I decided to transition to implementing Typescript. However, I've encountered an issue where accessing the child's methods through the parent's refs is causing problems.

Parent Code:

<template>
  <ref-test ref="child"/>
</template>

<script lang="ts">
import Vue from "vue";
import RefTest from "./RefTest.vue";

export default Vue.extend({
  name: "RefParent",
  components: {
    RefTest
  },
  data: () => ({}),
  methods: {},
  mounted() {
    const child = this.$refs.child as RefTest;
    child.pingMe();
  }
});
</script>

<style scoped></style>

Child Code:

<template>
  <div>REF TEST...</div>
</template>

<script lang="ts">
import Vue from "vue";

export default Vue.extend({
  name: "RefTest",
  data: () => ({}),
  methods: {
    pingMe() {
      console.log("refTest pingMe");
    }
  }
});
</script>

<style scoped></style>

The challenge I'm facing is that when referencing the child in the parent component with

const child = this.$refs.child as RefTest;
, I encounter the error message:
'RefTest' refers to a value, but is being used as a type here.
. Additionally, child.pingMe(); results in:
Property 'pingMe' does not exist on type 'Vue'.

I've attempted various solutions mentioned in discussions like this one: https://github.com/vuejs/vue/issues/8406, particularly focusing on interface definitions and the Vue.extend<> call.

Your assistance in clarifying the distinctions in utilizing Typescript would be greatly appreciated.

Answer №1

After conducting more experiments, I have come up with a working solution that may not be considered the most elegant but gets the job done without any compiler errors. Essentially, I defined an interface type that includes the necessary method. In the parent component, I cast the $ref as this interface type and everything seems to function correctly. If there is a better or more graceful way to achieve this, please do let me know. Below is the full code snippet for reference.

Declaration of Interface (types/refInterface.ts):

import Vue from "vue";

export interface RefInterface extends Vue {
  pingMe(): void;
}

Parent Component:

<template>
  <ref-test ref="child" />
</template>

<script lang="ts">
import Vue from "vue";
import RefTest from "./RefTest.vue";
import { RefInterface } from "@/types/refInterface";

export default Vue.extend({
  name: "RefParent",
  components: {
    RefTest
  },
  data: () => ({}),
  methods: {},
  mounted() {
    const child = this.$refs.child as RefInterface;
    child.pingMe();
  }
});
</script>

<style scoped></style>

The code within the 'child' component remains unchanged in order for this implementation to work effectively.

Answer №3

Although this question may be old, I stumbled upon it and felt compelled to share my solution for those who prefer not to create an interface every time they call a single method on a reference:

mounted() {
  const child = this.$refs.child as Vue & { pingMe: () => void };
  child.pingMe();
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Employing the Vue3 vue-ganttastic plugin within a Nuxt3 environment

Struggling to utilize the vue-ganttastic plugin. It looks amazing, but I just can't seem to get it working with Nuxt :frowning: I've had no issues integrating other Vue3 modules into Nuxt (such as jodit or echarts). I even successfully implemente ...

Error encountered in NextJS API: "TypeError: res.status is not a function"

Background In my development environment, I am using NextJS v11.1.1-canary.11, React v17.0.2, and Typescript v4.3.5. To set up a basic API endpoint following the guidelines from NextJS Typescript documentation, I created a file named login.tsx in the pag ...

Executing a Vue method from the main.js file within a Vue.js document

Why can't I call my method in App.vue? Shouldn't the div with id='App' in the App file allow me to access methods within it? Main.js new Vue({ render: h => h(App), methods:{ gesamt:function () { return 'Hello&a ...

Searching for values within an array of objects by iterating through nested arrays to apply a filter

Having trouble returning the testcaseid from an array to this.filteredArray Able to fetch header value and all values of the array when the search word is empty. Seeking assistance with iterating through the testcaseid and header on the search input fiel ...

Vue with DevXtreme DataGrid

Currently, I am working on creating a table using DataGrid in Vue. My goal is to populate the table with data from a v-for loop. However, I am facing some challenges in displaying the values such as {{user.name}}, {{user.email}}, and {{rol.name}}. As a beg ...

Understanding TypeScript's ability to infer types in generics

Exploring the world of TypeScript through a robustly typed system for REST requests. Let's dive into the code: This type is used to establish the connection between routes and their respective object types: export interface RoutesMapping { api1: ...

Update of Angular Material Table rows triggers a popup, however only the values from the first array are populated in all edited rows

Developed an application with two components (A & B) that includes a popup dialog for editing: Component A fetches the data from a service and loads it into a data table Component B initializes the data when a pop event is triggered from A. Usually, ...

The Safari keyboard navigation feature suddenly disappeared after uploading to Google App Engine

My current website is built using Vue.js (2.x) and deployed on Google App Engine. After testing the deployed application in Safari, I noticed that the accessibility feature "'skip navigation' on :focus" was no longer functioning proper ...

Is it best to make a refactored/service method public or private in Typescript?

Objective: I need to refactor a method in my component that is used across multiple components, and move it to a service class for better organization. Context: The method in question takes a user's date of birth input from a profile form and convert ...

Tips for embedding an object into an iframe source

I have successfully integrated a YouTube iframe into my HTML file. However, I would like the source URL to be dynamically generated based on data from the backend rather than manually inputting the URL as shown below. In the admin panel, there is an object ...

The assignment of type 'string' to type 'UploadFileStatus | undefined' is not permissible

import React, { useState } from 'react'; import { Upload } from 'antd'; import ImgCrop from 'antd-img-crop'; interface uploadProps{ fileList:string; } const ImageUploader:React.FC <uploadProps> ...

Struggling to use GroupBy on arrays with computed properties in Vue.js

I'm in need of assistance. Much appreciated. Here is an object I have: Funding : [ {person_id:'1'; Amount : '100'}, {person_id:'1'; Amount : '200'}, {person_id:'2'; Amount : '150'}, I am ...

retrieve and assign values to select input fields created dynamically

I have created several dropdown select fields using the following code: <tr v-for="(data,index) in dataList" :key="data.headers"> <td>{{ data.headers }}</td> <td>{{ data.sample }}</td> <td> ...

The type of Object.values() is not determined by a union or Records

When utilizing TypeScript, the Object.values() function encounters issues in deducing the accurate type from a union of Records: type A = Record<string, number>; type B = Record<string, boolean>; function func(value: A | B) { const propert ...

Async component with pagination does not activate setup() when the route is changed

Currently, I have a paginated component that uses the async setup() method to retrieve data from an API and populate the page. Everything works smoothly when the route is directly loaded. However, if I switch to a different page slug (for example, by click ...

Deduce the types of parameters in nested functions based on the parent object

Having encountered a challenging obstacle in my Typescript journey, I find myself facing a dilemma with building a command-parsing utility. My aim is to incorporate type hints within configuration objects. Let's delve into the code example below; int ...

Error in Laravel 5.5 PusherBroadcaster.php at line 106

I am facing a frustrating issue with the BroadcastException in PusherBroadcaster.php (line 106) error while using Laravel 5.5 and Vue 2.0. Despite trying various solutions, I have been unable to resolve it. Desperately seeking assistance. Here's what ...

"Need to refresh localStorage in VueJS after navigating back with this.$router.go(-1)? Here's how

Below is my Login.vue code: mounted() { if (localStorage.login) this.$router.go(-1); }, methods: { axios.post(ApiUrl + "/login") { ... } then(response => { ... localStorage.login = true; this.$router.go(0); ...

Vue.js - Launching Modal for Editing Data Entry

I have a list of records with corresponding buttons on the right side, as shown in this image: Whenever I click on one of these buttons, I want a dialog box to appear containing various input fields such as text inputs, dropdowns, and checkboxes. This dia ...

Unleashing the power of dynamic data imports in a Node.js application

My goal is to utilize the require function in a node/express application with typescript to import a json file. Here's how I attempted it: const url = `./data/${resource}.json`; const data = require(url); However, I encountered the error Cannot find ...