TypeScript改变了原生JS弱类型的特性,使得在开发阶段就能尽早防止潜在的运行时错误。TS的类型判断包括JS自带类型(String,Array,Boolean等)及用户自定义类型。
VUE发布了针对TS的官方类型申明,包含了VUE(https://github.com/vuejs/vue/tree/dev/types)、VUE Router(https://github.com/vuejs/vue-router/tree/dev/types)、Vuex(https://github.com/vuejs/vuex/tree/dev/types)
1、创建TS的Vue脚手架
1.1 生成脚手架
vue create hello-ts
创建时选择支持TypeScript特性

生成的项目目录结构如下,包含了
ts的配置,且js文件替换成了ts文件。
在package.json中可以看到根据用户选择自动引入ts相关的npm包

1.2 TS支持
脚手架中shims-vue.d.ts文件做类型申明,让ts能识别vue文件
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
shim-jsx.d.ts对jsx文件做类型补充说明
import Vue, { VNode } from 'vue'
declare global {
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {}
// tslint:disable no-empty-interface
interface ElementClass extends Vue {}
interface IntrinsicElements {
[elem: string]: any
}
}
}
也可以自定义类型补充来补充vue已经定义好的类型,叫做模块补充 (module augmentation)。可以对vue所有的types进行类型补充
例如:声明一个string类型的实例属性 $myProperty
// 1. 确保在声明补充的类型之前导入 'vue'
import Vue from 'vue'
// 2. 定制一个文件,设置你想要补充的类型
// 在 types/vue.d.ts 里 Vue 有构造函数类型
declare module 'vue/types/vue' {
// 3. 声明为 Vue 补充的东西
interface Vue {
$myProperty: string
}
}
在项目中可直接和vue自带的其他属性一样使用
var vm = new Vue()
console.log(vm.$myProperty) // 将会顺利编译通过
2、TS开发组件
Component组件为vue最基本的开发单元。要让TS能识别出Vue组件类型,则需要使用Vue.component或Vue.extend定义组件
2.1 基础使用: vue.extend
vue.extend(options)全局函数可以使用户定义一个vue的子类
// 加上 lang=ts 让webpack识别此段代码为 typescript
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
// ...
})
</script>
通过以上方式定义的Component,TS就能够开启类型识别,推断出它的类型
2.2 基于class: vue-class-component
vue-class-component官方库提供了componentTS 装饰器,能够像写 class 一样编写组件。点击查看更多
import Vue from 'vue'
import Component from 'vue-class-component'
import Hello from './components/Hello.vue'
// @Component 修饰符注明了此类为一个 Vue 组件
@Component({
// 所有的组件选项都可以放在这里
components: { Hello }
props: {
propMessage: String
},
watch: {
propMessage: function(val) {
this.msg = this.msg + ‘ ’ + val
}
}
})
export default class App extends Vue {
// 等价于 data() { return { msg: 'hello' } }
msg = 'hello';
// 等价于是 computed: { computedMsg() {} }
get computedMsg(): string {
return 'computed ' + this.msg
}
// 等价于 methods: { greet() {} }
greet() : void {
console.log(this.computedMsg())
}
// lifecycle hook
mounted () : void {
this.greet()
}
}
class-style的组件开发方式:
-
methods: 声明为类函数。如上例中的greet() -
computed属性: 声明为get 类属性访问器。如上例中的computedMsg() -
data: 声明为类属性。如上例中msg -
vue methods: vue的 data/render/生命周期函数,都可以申明为类函数。如上例中的mounted -
其他vue的options: 其他vue options,如 components,props,watch等,放在component装饰器里(所有vue options原则上都可以放在此处),写法保持原来的vue options写法。如上例的props
2.3 扩展装饰器
vue-property-decorator是个非官方库,在 vue-class-component 上增强更多的结合 Vue 特性的装饰。为原本需要放在@components里的options(components,props,watch等)提供装饰器。点击查看更多
@Prop@PropSync@Model@Watch@Provide@Inject@ProvideReactive@InjectReactive@Emit@Ref-
@Component(provided by vue-class-component) -
Mixins(the helper function namedmixinsprovided by vue-class-component)
vue-property-decorator也提供了vue-class-component的功能,文件中只引入这一个包即可。但安装依赖时要安装vue-class-component
上面的例子就改为
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
import Hello from './components/Hello.vue'
// @Component 修饰符注明了此类为一个 Vue 组件
@Component({
components: { Hello }
})
export default class App extends Vue {
@Prop() private proMessage!: String
@Watch('msg')
onMsgChanged(val: string, oldVal: string) {
this.msg = this.msg + ‘ ’ + val
}
// 等价于 data() { return { msg: 'hello' } }
msg = 'hello';
// 等价于是 computed: { computedMsg() {} }
get computedMsg(): string {
return 'computed ' + this.msg
}
// 等价于 methods: { greet() {} }
greet() : void {
console.log(this.computedMsg())
}
// lifecycle hook
mounted () : void {
this.greet()
}
}
参考文章