本文是繼 Vue + TypeScript 新項目起手式 以後的進階+踩坑配置,因此推薦先行閱讀前文 javascript
完整閱讀完以後,基本能夠順利在新項目中使用
vue
+typescript
了html
另外特別注意!!! vue
不推薦在已有項目上強加
typescript
, 因ts寫法的組件跟以前的組件不兼容,若上的話須要修改以前寫的組件java
配置完整版可參考 vue-typescript-starter,若沒配置出來,也能夠對照修改配置node
直接進入正題:jquery
ts
支持 render jsx
寫法webpack
ts
支持 es6 / es67
git
配置 vuex
es6
vue
識別全局方法/變量github
支持 mixin
支持 ProvidePlugin
的全局變量,好比 lodash
的_
這裏一共分兩步
首先得先讓 vue
支持 jsx
寫法
再讓 vue
中的 ts
支持 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
,以下圖:
首先配置 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
了,切記!!!
在 tsconfig.json
中,添加對es6 / es7
的支持,更多的配置請見tsconfig - 編譯選項
"lib": [ "dom", "es5", "es6", "es7", "es2015.promise" ]
否則的話,連Object.assign
這種最基本的函數也會在ts
中報錯,真的使人難過
這裏就比較簡單了
# 安裝依賴 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'] } }
在項目中使用 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()的話就不會報錯了
我在vue-property-decorator
裏裏外外找了好幾圈,缺沒有找到mixin
這個修飾器
// 若是全局mixin,那也太蠢了 Vue.mixin( mixin )
找很是多的 ts + vue
項目,可是沒有找到我理想的mixin
的方式,
那麼就本身進行探索咯,下圖是我本身使用的目前最佳mixin
方式:
聲明瞭一個mixin組件,以下圖:
其實就是我在mixin
中聲明瞭聲明屬性 / 方法,那麼我就在vue
實例中聲明這個屬性 / 方法
使用方式以下圖:
若是咱們在項目中有使用 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-typescript-starter,若沒配置出來,也能夠對照修改配置
在剛上typescript
的時候,我是拒絕的,嫌棄每一個地方都要聲明類型,否則就走不下去,可是若是讓大家作如下一個選擇題:
在編譯時發現問題
仍是運行時發現問題
我會堅決果斷選擇前者,這是ts強類型帶給我最大的亮點