深入使用Vue + TS
Posted cczlovexw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入使用Vue + TS相关的知识,希望对你有一定的参考价值。
深入使用TS
支持 render jsx 写法
这里一共分两步
-
首先得先让
vue
支持jsx
写法 -
再让
vue
中的ts
支持jsx
写法
让 vue 支持 jsx
按照官方做法,安装Babel 插件
安装依赖
npm install babel-plugin-syntax-jsx babel-plugin-transform-vue-jsx babel-helper-vue-jsx-merge-props babel-preset-es2015 --save-dev
在.babelrc
中添加:
{ "plugins": ["transform-vue-jsx"] }
之后就可以这些写render
,如下图:
让 ts 支持 jsx
首先配置 webpack
找到./build/webpack.base.conf.js
-
找到
resolve.extensions
里面加上.tsx
后缀
resolve: { extensions: [‘.js‘, ‘.vue‘, ‘.json‘, ‘.ts‘, ‘.tsx‘] }
-
找到
module.rules
修改webpack对.tsx
.ts
的解析
module: { rules: [ { test: /.(js|vue)$/, loader: ‘eslint-loader‘, enforce: ‘pre‘, include: [resolve(‘src‘), resolve(‘test‘)], options: { formatter: require(‘eslint-friendly-formatter‘) } }, // 从这里复制下面的代码就可以了 // 如果之前按照起手式配置的同学,请替换配置 { test: /.tsx?$/, exclude: /node_modules/, enforce: ‘pre‘, loader: ‘tslint-loader‘ }, { test: /.vue$/, loader: ‘vue-loader‘, options: Object.assign(vueLoaderConfig, { loaders: { ts: "ts-loader", tsx: "babel-loader!ts-loader" } }) }, { test: /.tsx?$/, exclude: /node_modules/, use: [ "babel-loader", { loader: "ts-loader", options: { appendTsxSuffixTo: [/.vue$/] } } ] }, // 复制截止 { test: /.js$/, loader: ‘babel-loader‘, include: [resolve(‘src‘), resolve(‘test‘)] },
上面的配置,主要意思是 vue
文件识别ts/tsx
代码的时候,先过一遍ts-loader
,在过一遍babel-loader
,我知道这听起来有点蠢,但是jsx
不能不要对吧?
然后在 tsconfig.json
中,添加对jsx
的支持
"compilerOptions": { "jsx": "preserve" }
之后就可以顺利在.vue
单文件中的ts
写jsx
代码了,如下图所示:
敲黑板,这里又有重点,使用
jsx
写法的话, 一定要使用.tsx
,不要用.ts
了,切记!!!
支持es6 / es7
在 tsconfig.json
中,添加对es6 / es7
的支持,更多的配置请见tsconfig - 编译选项
"lib": [ "dom", "es5", "es6", "es7", "es2015.promise" ]
不然的话,连Object.assign
这种最基本的函数也会在ts
中报错,真的令人难过
配置 vuex
这里就比较简单了
# 安装依赖
npm i vuex vuex-class --save
-
vuex:在
vue
中集中管理应用状态 -
vuex-class :在
vue-class-component
写法中 绑定vuex
Store
的配置跟原来一模一样,引用的时候有一点区别,下面的例子介绍了用法,应该一看便知,这里我不做赘述
import Vue from ‘vue‘ import Component from ‘vue-class-component‘ import { State, Getter, Action, Mutation, namespace } from ‘vuex-class‘ const ModuleGetter = namespace(‘path/to/module‘, Getter) @Component export class MyComp extends Vue { @State(‘foo‘) stateFoo @State(state => state.bar) stateBar @Getter(‘foo‘) getterFoo @Action(‘foo‘) actionFoo @Mutation(‘foo‘) mutationFoo @ModuleGetter(‘foo‘) moduleGetterFoo // If the argument is omitted, use the property name // for each state/getter/action/mutation type @State foo @Getter bar @Action baz @Mutation qux created () { this.stateFoo // -> store.state.foo this.stateBar // -> store.state.bar this.getterFoo // -> store.getters.foo this.actionFoo({ value: true }) // -> store.dispatch(‘foo‘, { value: true }) this.mutationFoo({ value: true }) // -> store.commit(‘foo‘, { value: true }) this.moduleGetterFoo // -> store.getters[‘path/to/module/foo‘] } }
让 vue 识别全局方法/变量
在项目中使用 ui 组件是很正常的操作
比如使用 Element-uI
的 meesage
,用法如下图:
this.$message({ message: ‘恭喜你,这是一条成功消息‘, type: ‘success‘ })
但是在配置了 typescript
之后
那是因为 $message
属性,并没有在 vue
实例中声明
解决办法也非常简单,那我们就声明一下呗
在之前文章中创建的 src/vue-shim.d.ts
文件中,增加如下代码:
// 声明全局方法 declare module ‘vue/types/vue‘ { interface Vue { $Message: any, $Modal: any } }
这样,之后再使用this.$message()的话就不会报错了
支持 mixin
我在vue-property-decorator
里里外外找了好几圈,缺没有找到mixin
这个修饰器
// 如果全局mixin,那也太蠢了 Vue.mixin( mixin )
找非常多的 ts + vue
项目,但是没有找到我理想的mixin
的方式,
那么就自己进行探索咯,下图是我自己使用的目前最佳mixin
方式:
声明了一个mixin组件,如下图:
其实就是我在mixin
中声明了声明属性 / 方法,那么我就在vue
实例中声明这个属性 / 方法
使用方式如下图:
支持 ProvidePlugin 的全局变量,比如 lodash 的 _
如果我们在项目中有使用 jquery,lodash
这样的工具库的时候,肯定不希望在所有用到的地方都import _ from ‘lodash’
@types/lodash
那我们就来配置一下:
首先还是在webpack.base.conf.js
中添加一个插件、并把这个 vendor
拉出来
entry: { app: ‘./src/main.ts‘, vendor: [ "lodash" ] } plugins: [ new webpack.ProvidePlugin({ _: ‘lodash‘ }) ]
上面的意思是,当模块使用这些变量的时候wepback
会自动加载
然后,你需要告诉eslint
这个 _
是全局的
在.eslintrc.js
中添加
globals: { _: true },
接下来,你还需要告诉ts
这个 _
是全局的
在vue-shim.d.ts
declare global { const _: typeof lodash }
如果没有上面这段声明,但是在
ts
中使用的话,会报如下的错误:
这个问题Consider allowing access to UMD globals from modules · Issue #10178 · Microsoft/TypeScript · GitHub
有一个很简单的解释,就是害怕你全局声明的_
跟 import _ from ‘lodash‘
的行为不一致,这样的话,之后会留下隐患
以上是关于深入使用Vue + TS的主要内容,如果未能解决你的问题,请参考以下文章