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
官方库提供了component
TS 装饰器,能够像写 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 namedmixins
provided 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()
}
}
参考文章
网友评论