开篇说明:我用的vue-property-decorator这个装饰器库,分享下我的流程和踩的一些坑)
1.环境的配置
-
1.安装基础以来 typescript,ts-loader,vue-property-decorator
-
2.编写tsconfig.json (tsconfig配置文件,这边用的是官方默认的版本)
{
"compilerOptions": {
"sourceMap": true,
"types": ["node"],
"strict": true,
"module": "es2015",
"moduleResolution": "node",
"target": "es5",
"experimentalDecorators": true
},
"include": [
"./src/**/*"
],
"lib": [
"dom",
"es2015",
"es2015.promise"
]
}
- 3.webpack配置ts-loader
我们这边就是配置vue.config.js
// resolve配置
resolve: {
...,
extensions: [".ts", ".js", ".vue", ".json"], //加上ts
...
},
// loader配置,添加一个tsx?$的配置,匹配ts(tsx)文件
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [ /\.vue$/ ],
appendTsxSuffixTo: [ /\.vue$/ ]
}
}
]
}
- 4.src目录添加vue模块、tsx模块注入配置文件 vue-shims.d.ts tsx-shims.d.ts
这块有个要注意的:我们常用一个route,$message之类的,一定要预先这义好类型
declare module "vue/types/vue" {
interface Vue {
$router: VueRouter;
$route: Route;
$Message: any;
}
}
踩坑:
- 1.
TS2688: Cannot find type definition file for 'node'服务启动后在tsconfig.json文件里会这样的一个错误,这个错误是因为少装了一个包,我们需要在开发依赖里加"@types/node"这个包,还有一种,可以把types:[]置成空数组,也能解决,但不推荐,因为这块本身官司的思路就要引入types指定的列出来的包。这块具体的可以去看文档里的@types,typeRoots和types
(@types下面是所引放第三方库的静态资源文件,比如我们要引入echarts插件,需要先安装@type/echarts,这样就可以引用到了,总结,@types是npm的一个分支,用来存放*.d.ts文件,如果对应的npm包存放在@types种,要使用必须下载!如果是自己本地的*.d.ts申明文件,则和@types没有任何关系!)
这里有一个重点,当我们引用的第三方库没有对应该的在.d.ts文件怎么办,这个时候我需要声明他的类型,比如我这个项目里用到了v-charts,我们需要在src目录下新建一个v-charts.d.ts文件,内容为declare module 'v-charts/lib/line'
-
2.引用组件必须要写上.vue后缀,不然会报错
-
3.$router我们常用的可能有这样写法
liClick (id: number) { this.$router.push({ path: '/dashboard/topDetail', query: {id: id} }) }看起来好像没有问题,其实是有问题的,从源码里我们可以看到$router是RawLocation这个类型的
export type RawLocation = string | Location;export interface Location { name?: string; path?: string; hash?: string; query?: Dictionary<string | string[]>; params?: Dictionary<string>; append?: boolean; replace?: boolean; }type Dictionary<T> = { [key: string]: T }接收的obj里的key的键值是string,所以要把
query: {id: id}改成query: {id: id.toString} -
4.json的引入
import business from 'src/assets/data/business.json'=>const business = require('src/assets/data/business.json')
2.使用vue-property-decorator库对应语法的装饰器
各装饰器基本上文档上都有写,这里就不再搬运了,只说下自己踩的坑。
@Emit()
在父级组件传一个事件给子集我常用写法@liClick='liClick',这个时候在子组件里按文档写法@Emit() liClick(id: number){ return id },这样写就有问题,按文档里所说,如果不写事件参数,会默认认使用函数名称,同时,camelCase名称将转换为kebab-case,那我们的函数名称叫liClick,转成kebab-case写法就是li-click,我们传进来的事件叫liClick,不是一个东西,事件无法触发了,两种解决,一种是给事件参数@Emit('liClick') liClick(id: number){ return id }这样就Ok,第二种就是父级传进来的时候@li-click='liClick'传进来的时候事件参数保持一致。
Mixins
不能使用private修饰,混入的时候,两个私有属性混入时,会产生冲突,使用protected修饰
按着上面的做法走,基本上大家应该都可以应用TS了,遇到问题去百度下也差不多能解决.