// ExampleMixin.vue export default Vue.extend({ data () { return { testValue: 'test' } } }) // other.vue export default Vue.extend({ mixins: [ExampleMixin], created () { this.testValue // error, testValue 不存在! } })
我们需要稍作修改:
// other.vue export default ExampleMixin.extend({ mixins: [ExampleMixin], created () { this.testValue // 编译通过 } })
但这会存在一个问题,当使用多个 mixins 且推断出类型时,这将无法工作。而在这个 Issuse 中官方也明确表示,这无法被修改。
使用 vue-class-component 这会方便很多:
// ExampleMixin.vue import Vue from 'vue' import Component from 'vue-class-component' @Component export class ExampleMixin extends Vue { public testValue = 'test' } // other.vue import Component, { mixins } from 'vue-class-component' import ExampleMixin from 'ExampleMixin.vue' @Component({ components: { ExampleMixin } }) export class MyComp extends mixins(ExampleMixin) { created () { console.log(this.testValue) // 编译通过 } }
也支持可以传入多个 mixins。
一些其它
做为 Vue 中最正统的方法(与标准形式最为接近),Vue.extends() 有着自己的优势,在 VScode Vetur 插件辅助下,它能正确提示子组件上的 Props:
而类做为 TypeScript 特殊的存在(它既可以作为类型,也可以作为值),当我们使用 vue-class-component 并通过 $refs 绑定为子类组件时,便能获取子组件上暴露的类型信息:
导入 .vue 时,为什么会报错?
当你在 Vue 中使用 TypeScript 时,所遇到的第一个问题即是在 ts 文件中找不到 .vue 文件,即使你所写的路径并没有问题:
在 TypeScript 中,它仅识别 js/ts/jsx/tsx 文件,为了让它识别 .vue 文件,我们需要显式告诉 TypeScript,vue 文件存在,并且指定导出 VueConstructor:
declare module '*.vue' { import Vue from 'vue' export default Vue }
但是,这引起了另一个问题,当我们导入一个并不存在的 .vue 文件时,也能通过编译:
是的,这在情理之中。
当我尝试在 .vue 文件中导入已存在或者不存在的 .vue 文件时,却得到不同的结果:
文件不存在时:
文件存在时:
文件不存在时,引用 Vue 的声明文件。文件存在时,引用正确的文件定义。
这让人很困惑,而这些都是 Vetur 的功劳。
在这个 PR 下,我找到相关解答:这个 PR 里,Vetur 提供解析其他 .vue 文件的功能,以便能获取正确的信息,当 .vue 文件不存在时,会读取 .d.ts 里的信息。
参考
https://github.com/vuejs/vue/pull/5887
https://github.com/vuejs/vue/issues/7211
https://github.com/vuejs/vue/pull/6856
https://github.com/vuejs/vetur/pull/94
您可能感兴趣的文章: