使用 TypeScript 编写 Vue 单文件组件:vue-class-component 或者 Vue.extend
如果你想要在 Vue 中使用 Typescript,那么你首先需要确保你的 Vue 文件是类型安全的。
只需要将 lang="ts"
添加到你的 .vue
文件的脚本标识中,但像往常一般编写可直接运行的正常组件,那么或许你将错过 90% 由 Typescript 所提供的工具支持。
本文将介绍两种用 Typescript 编写 Vue 组件的推荐方法,两者都是在 Vue 文档中支持的。supported in the Vue documentation.
vue-class-component( Vue 类组件)
vue-class-component 是一个 ES / Typescript 修饰符,可以为用户提供编写 类风格 Vue 组件的能力。它通常与 vue-property-decorator 一起来使用。
以下是使用 vue-class-component 编写的组件示例:
<script lang="ts">
import Component from "vue-class-component"
import { Prop } from "vue-property-decorator"
type ComplexObjectInterface = {
testProp: string
modelName: number
}
@Component
export default ComponentName extends Component {
@Prop({
type: Object
})
propExample: ComplexObjectInterface
dataExample: string = "This Property Will Be Data"
get computedExample() {
return this.dataExample + this.propExample.testProp + "Computed Property Example";
}
methodExample() {
this.dataExample = "This is being done in a method"
}
}
</script>
该类按照如下所示的规则蓝图,映射到 Vue 组件中:
- 组件数据 → 在类中定义和实例化的任意属性
- 计算属性 → getters
- 组件方法 → 在类中定义的任意方法
- 组件属性 → 使用 @prop() 装饰器定义属性或作为 @component 装饰器的参数( 示例在此)
直到最近,这一直是确保 Vue 组件类型安全的唯一方法。
Vue.extend()
最新版的 Vue 重构了部分 TypeScript 代码,所以我们有了一种新的使用 TypeScript 编写 Vue 组件的方式:Vue.extend。
我称之为 经典方法,因为这与标准 Vue 组件从字面上看完全相同,不过它必须显示的包装在 Vue.extend 中。
基于最新的变更及类型推断,TypeScript 编译器目前可以根据对象结构和在 Vue.extend() 中的参数,自动为 Vue 组件提供类型支持。
<script lang="ts">
import Vue, { PropTypes } from "vue"
type ComplexObjectInterface = {
testProp: string
modelName: number
}
export default Vue.extend({
props: {
propExample: {
// 注:此功能尚不存在
// 查看如下 github 分支获取更多信息
// https://github.com/vuejs/vue/pull/6856
type: Object as PropTypes<ComplexObjectInterface>
}
},
data() {
return {
dataExample: "This Property Will Be Data"
}
},
computed: {
computedExample(): string {
return (
this.dataExample +
this.propExample.testProp +
"Computed Property Example"
)
}
},
methods: {
methodExample() {
this.dataExample = "This is being done in a method"
}
}
})
</script>
这与 vue-class-components
(Vue 类组件)一个重要区别的是,它是基本的 Object(对象) 而不是 Class(类)。
此外,由于这是定义 Vue 组件的经典方式,所以基本所有的 Vue 工具都能做到开箱即用 (如 Vetur
)。
Vetur 可以对组件定义智能感知。
哪一种方式更优?
特性 | vue-class-component | Vue.extend |
---|---|---|
自动识别组件中的 Prop |
x | ✅ |
Props 类型安全 |
✅ | x |
Data 类型安全 |
✅ | ✅ |
Computed 属性类型安全 |
✅ | ✅ |
Methods 类型安全 |
✅ | ✅ |
当你阅读到这里的时候请注意,这些只是风格差异,实际上它们可以做完全相同的事。
对于我个人而言,我更喜欢 Vue.extend 这样的方式,因为我相信它更容易讲授和理解。从风格上来说,它更像是把 Typescript 放进了 Vue 之中,而不是把 Vue 强行添加到 Typescript 之中。
额外的抽象层不值得这么方便,特别是对于typed-props即将推出。
如果您有需要自定义键入的复杂属性(props),那么vue类组件可能更有意义。在当前版本中,不能使用Vue.扩展来隐式地将属性(props)转换为类/接口.
目前,这两项都包含在官方文件中,因此这两项都将得到支持。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。