Vue和Typescript:在访问子组件的方法时如何避免TS错误

时间:2019-08-08 16:24:47

标签: typescript vue.js

我已经创建了一个基于类的自定义vue组件,并且试图从父组件访问其方法和/或计算的属性。 Vue文档中有一个示例,该示例解释了我正在尝试做的事情(https://vuejs.org/v2/guide/components-edge-cases.html#Accessing-Child-Component-Instances-amp-Child-Elements)。所以基本上就是这个

class ParentComponent extends Vue {
    someMethod() {
        (this.$refs.myChildRef as ChildComponent).focus()
    }
}

class ChildComponent extends Vue {
    focus() {
        // do something
    }
}

现在,这会导致TS错误: “ TS2339:属性'focus'在类型'Vue'上不存在”

因此,显然,打字稿看不到我的ChildComponent还有其他方法。

尽管该代码在运行时仍可运行,所以它似乎只是一个打字稿问题。

有人知道如何解决吗?

4 个答案:

答案 0 :(得分:2)

选项1:忽略

//@ts-ignore

选项2:键入任意

const child: any = this.$refs.myChildRef;
child.focus();

选项3:界面,如@LLai所述

interface ComponentInterface {
    focus: () => void
}

选项4:合并类型

像@LaLai所说的那样一个班轮

(this.$refs.myChildRef as ChildComponent & { focus: () => void }).focus()

或者如果您更需要它

Class ParentComponent extends Vue {
    $refs: Vue["$refs"] & {
      myChildRef: { focus: () => void }
    };  
}

答案 1 :(得分:1)

一种解决方案是在子组件上实现接口。

interface ComponentInterface {
    focus: () => void
}

class ChildComponent extends Vue implements ComponentInterface {
    focus () {
        // do something
    }
}

另一种选择是合并类型

class ParentComponent extends Vue {
    someMethod() {
        (this.$refs.myChildRef as ChildComponent & { focus: () => void }).focus()
    }
}

但是,如果您在子组件之外调用焦点很多,这可能会重复。我更喜欢选项1。

答案 2 :(得分:0)

使用打字稿构建的组件也存在类似问题。我们目前使用的解决方案是,在每个问题之前添加ts-ignore注释。这不是最好的方法,但是可以。

//@ts-ignore

尝试

答案 3 :(得分:0)

我不想两次声明方法名称,所以我使用这种方式:

在ChildComponent.ts

import Vue from 'vue'

export default class ChildComponent extends Vue.extend({
    methods: {
        focus() {}
    }
}){}

在ChildComponent.vue中

<template>...</template>

<script lang="ts">
    import ChildComponent from './ChildComponent'

    export default ChildComponent;
</script>

在ParentComponent中

import Vue from 'vue'

import ChildComponent from './ChildComponent.vue'
import ChildComponentClass from './ChildComponent'

export default class ParentComponent extends Vue.extend({
    components: {ChildComponent},
    methods: {
        someMethod() {
            (<ChildComponentsClass>this.$refs.child).focus();
        }
    }
}){}