如何导入具有正确类型的 Vue 类组件?

Posted

技术标签:

【中文标题】如何导入具有正确类型的 Vue 类组件?【英文标题】:How can I import a Vue class component with proper types? 【发布时间】:2020-05-04 10:14:27 【问题描述】:

如果我有一个单文件的 Vue 类组件,例如:

// MyComponent.vue
<template>
  <div></div>
</template>

import Vue from 'vue'
import Component from 'vue-class-component'

@Component(
)
export default class MyComponent extends Vue 
  public message: string = 'Hello!'

然后我将它导入到其他地方,并获取它的一个实例。

import MyComponent from "./MyComponent.vue";
...
const foo = ... as MyComponent;
foo.message = "goodbye";

使用标准 Vue CLI 3 设置会出现错误,因为它包含 shims-vue.d.ts 和以下内容:

declare module "*.vue" 
  import Vue from "vue";
  export default Vue;

据我了解,这意味着每当您编写import Foo from "./Foo.vue" 时,Foo 将只是Vue 的别名,您将无法访问其成员。

如果您从.ts 文件导入,情况似乎确实如此。如果您从 .vue 文件导入,它会神奇地工作!

不幸的是,我所有的测试都是.spec.ts 文件,所以我无法导入任何组件的类型。这使得测试变得困难。有没有办法解决这个问题?

【问题讨论】:

我真的不认为这是使用组件的方式。您不应该以这种方式从父组件中更改子组件的成员。更好的方法是使用emitters and bindings 是的,我也听说过 React,但是你如何处理一次性事件?就像“如果用户单击此按钮,它应该折叠所有树节点”?您最终不得不基本上将所有状态和逻辑移动到需要访问其中任何一个的最顶层组件,这是一个非常垃圾的解决方案。无论如何,发射器和绑定在 Vue 中的类型也非常糟糕。我想我会切换到支持正确输入的 React。 问题不在于 Vue 本身,而在于使用了已弃用的类组件。尽管他们是班级,但他们对 TS 来说从来都不够好。必须改用 Composition API,它以类似于 React 的方式对 TS 友好。 我查看了组合 API,但它肯定仍然不如 React/TSX 对 TS 友好。 【参考方案1】:

我在 Vue 2 和 Vue 3 项目中的做法如下:

    创建一个 Foo.vue 文件并将 script 标签添加到 Foo.vue.ts 文件中。这里是sn-p。

    <template>
       <div>... Your template code here ...</div>
    </template>
    
    <script lang="ts" src="./Foo.vue.ts" />
    

    在 Foo.vue.ts 文件中编写组件代码。

import Vue from 'vue'
import Component from 'vue-class-component'

@Component(
)
export default class MyComponent extends Vue 
  public message: string = 'Hello!'

    现在您可以使用as 关键字。
import MyComponent from "./MyComponent.vue";
...
const foo = obj as MyComponent;
foo.message = "goodbye";

【讨论】:

以上是关于如何导入具有正确类型的 Vue 类组件?的主要内容,如果未能解决你的问题,请参考以下文章

在单个组件中从“vue”导入 Vue 是不是正确?

导入的组件和控制台消息

从 Vue 组件内部的 URL 导入 PayPal(或任何其他脚本)

如何在 Typescript 中正确使用 React.lazy() 来导入带有泛型类型参数的反应组件?

具有单个文件组件的 WordPress Vue 插件 - 无法使用导入

如何用导入的方法装饰 typescript vue 类组件?