随着 TypeScript 的热度越来越高,Vue 官方提供的 TypeScript 支持也越来越多,Vue-CLI 3.0 更是直接提供了使用 TypeScript 来创建一个新工程的功能。
使用 Vue 进行开发也已经有半年的时间了,也非常怀念当时拿 TypeScript 写 Angular 的那种得心应手的舒畅,因此,在这个周末,花了一下午时间,将手头的一个 Vue 小 Demo 从 Js 修改成 Ts,打算看一下,Vue的 TypeScript 开发,到底靠谱不靠谱。
本篇博客,就来记录一下项目升级到 TypeScirpt 中的一些重点和遇到的坑吧。
项目搭建
新建项目
首先,我尝试将原有的 Vue
项目直接改动到 TypeScript
,但发现改造起来是比较麻烦的,需要再去安装各种相关依赖,调整打包配置,修改组件的代码写法。
所以我决定直接新建一个 TypeScript
的 Vue
项目,然后将旧项目迁移过来。
在Vue-CLI 3.0
中,提供了直接创建一个 TypeScript
项目的功能。具体如下:
如果未安装
Vue-CLI
,直接使用下面命令安装1
npm install -g @vue-cli
如果已安装,使用下面命令新建一个
Vue
项目,创建时选择手动选择特性(Manually select features)选项来添加Typescript
支持。1
vue create my-project-name
通过上面的命令,我们就创建了一个新的有TypeScript
支持的 Vue
项目。
迁移旧项目
当然,如果我们想将旧的Vue
项目改造为新的项目的话,虽然比较麻烦,但也是可行的。需要以下几个步骤:
npm
安装TypeScript
npm
安装ts-loader
,用于为webpack
提供.ts
文件的打包编译支持修改
webpack
的rules
配置,添加关于打包.ts
文件的配置。类似如下:1
2
3
4
5
6
7{
test: /\.ts$/,
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/],
}
}同时修改
extensions
选项,添加.ts
声明,使打包时可以识别.ts
文件。创建 Ts 的项目配置文件
tsconfig.json
,需要注意的是,尽量打开配置的strict
模式,才能保证Ts
对类似this
的类型检查。更多的配置项,例如支持JSX
,生成sourceMap
文件等选项,可以自行查看Typescript配置项文档将项目打包入口文件
main.js
修改为main.ts
增加
Vue
文件的类型声明。因为Typescript
是不支持Vue
文件的,所以我们通过自定义的将Vue
文件声明为一个模块,来保证Ts
对其的正确处理。定义一个
vue-shims.d.ts
文件,放在项目任意位置,内容如下1
2
3
4declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
通过以上几步,项目的Typescript
配置就算完成了,通过将.vue
文件的<script lang="js">
标签修改为<script lang="ts">
,就可以开始在项目中开始使用typescript
了。
代码编写
vue-class-component
使用 Ts
编写 Vue
代码,Vue
官方提供了一个库 Vue-class-component,用于让我们使用Ts
的类声明方式来编写vue
组件代码。
这个库提供了一个@Component
装饰器,基本使用方法如下:
1 | import Vue from 'vue' |
我们以前书写组件的data
数据项,可以直接声明为组件类的属性,methods
,可以直接声明为类的方法,组件的各种生命周期函数,也可以直接作为类方法声明。而计算属性,更可以方便的通过类的get
和set
函数来实现。
需要注意的是,因为Ts
的模块系统只能自动识别.ts
结尾的文件,因此我们在从.Vue
文件导入组件类时,需要在导入路径上加上文件名后缀.vue
。
对于一些无法在Ts
类中声明的方法和属性,例如watch
,props
我们可以直接在@Component
装饰器中作为参数传入,或者使用下面这个库。
vue-property-decorator
这个库依赖于上面的vue-class-component
,提供了更多的 Vue 组件相关方法的装饰器,可以让我们方便的在组件类中使用 Vue 实例提供的方法和属性,例如props
, watch
等。
vue-property-decorator
提供了下面几个装饰器:
@Watch
@Prop
@Model
@Provide
@Inject
@Emit
@Mixins
@Component
(依赖于vue-class-component
)
通过这些装饰器,我们可以简单方便的使用Vue
实例自身提供的一些方法和属性。如下:
1 | import { Vue, Component, Prop, Watch } from 'vue-property-decorator' |
具体这些装饰器的详细使用,可以前往vue-property-decorator项目主页 查看。
vuex-class
vuex-class
同样是基于vue-class-component
的一个库,用于提供vuex
的typeScript
支持。提供了以下几个装饰器:
@State
@Getter
@Action
Mutation
同时它还提供了一个namespace
方法,用于获取vuex
的某个命名空间。
vuex-class
的具体细节,也可以前往其项目主页 查看。
坑
有了上面提到的三个库,基本的开发应该就可以顺利的进行了。当然,因为Vue
对TypeScript
的支持还并不是非常完美,所以在使用的过程中可能还是会遇到一些坑,我这里说几个比较容易遇见的问题和解决办法。
使用装饰器时Ts 报错
这个问题,在tsconfig.js
中设置experimentalDecorators
选项为true
即可。
第三方库引入
我们在项目中会经常使用一些第三方的库,例如ElementUI
,echarts
等等,当我们在Ts
中引入这些库的时候,明明我们已经安装了,Ts
仍然会报错找不到库路径。这是因为这些库中没有包含以.d.ts
结尾的库声明文件,所以Ts
就无法识别它们。
比较方便的解决办法是前往这个网站查看是否有对应第三方库的声明,如果有,直接使用npm
安装即可。在这个网站,基本可以找到我们常用的所有库的声明type
库。
当然,如果我们用的第三方库比较冷门的话,这个网站我们搜不到,我们也可以自己写一个声明文件放在项目中,并不是特别麻烦。
Vue全局方法和属性的使用
在写Vue
的时候,我们通常会定义或使用第三方提供的全局方法,在TypeScript
中照原来的方法使用的话,会报错Vue
类型并不存在这个全局属性或方法。这是因为我们没有为Vue
类型声明对应的属性和方法。
可以通过在上文提到的vue-shim.d.ts
中添加对应的方法和属性声明,来避免这个报错。
例如elementUI
提供的全局方法$message
1 | declare module 'vue/types/vue' { |
属性也是一样,在Vue
的interface
中声明即可。
总结
总的来说,在Vue
中使用TypeScript
目前是完全可行的,当然,还是远远比不上Angular
和TypeScript
的那种非常契合丝滑的感受的。但也情有可原,毕竟vue
框架的作者尤大大一年前还在知乎严肃的说Vue
并不特别需要TypeScript
,Vue
这个框架诞生之初也并没有想与Ts
发生什么联系,就算现在想借助TypeScirpt
来提高Vue
在大型的长期项目中的开发效率,降低维护难度,也不是短期内就可以完成的事情。
但有理由相信,随着前端工程化程度的进一步深入,Vue
也会加大与Typescript
的结合力度,来进一步为我们提供更好的开发体验的。
另外,附上我使用 Vue-CLI
搭建的Vue + TypeScirpt
项目链接,有需要的同学可以参考一下。
谢谢阅读。