shims-vue 文件有什么用
· 阅读需 4 分钟
shims-vue.d.ts 文件在 Vue 项目(特别是使用 TypeScript 的 Vue 2 项目)中起到声明模块的作用。
shims-vue.d.ts
因为 Vue 文件(.vue)是单文件组件(SFC),TypeScript 默认无法识别其模块类型,因此在引入 .vue 文件时会报错:Cannot find module 'xxx.vue'。
为了解决这个问题 ,我们通常会在项目中添加一个 shims-vue.d.ts 文件,为 TypeScript 提供模块声明,让 TypeScript 识别 .vue 文件的模块类型。这个文件的内容通常如下:
// src/shims-vue.d.ts
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
在 Vue 3 中,使用的是新的 SFC 模块类型 DefineComponent:
// src/shims-vue.d.ts
declare module '*.vue' {
import { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
通过这样的声明,TypeScript 就能正确识别 .vue 文件并进行类型检查,避免模块识别错误。
提示
Q: 为什么有时候没有这段声明,编辑器也能正常识别 vue 文件?
A: 很有可能是因为编辑器的插件完成了这个工作。比如 vscode 中的 "TypeScript Vue Plugin(Volar)"
如何扩展 Vue 的属性
注意
shims-vue.d.ts 是一个全局变量的声明文件,不能在顶部出现 import, export
官方文档: 增强类型
// plugins/types.d.ts
// 这里必须在顶部引入 vue
// 因为第三方插件都是扩展的顶部 vue 的属性
// 如果在 declare 内部 import, 会丢失三方插件扩展的属性
// 因此, 该声明只能写成一个模块,只能在插件中手动引入这个类型的扩展
import Vue from 'vue'
declare module 'vue/types/vue' {
// var vm = new Vue()
// console.log(vm.$myProperty) // 将会顺利编译通过
interface Vue {
$myProperty: string
[key: string]: any
}
// console.log(Vue.$myGlobal)
interface VueConstructor {
$myGlobal: string
[key: string]: any
}
}
// var vm = new Vue({
// myOption: 'Hello'
// })
declare module 'vue/types/options' {
interface ComponentOptions<V extends Vue> {
myOption?: string
[key: string]: any
}
}