Vue + TypeScript踩坑(初始化項目)
- 前言,最近公司新項目需要進行重構,框架選擇為Vue+TypeScript,記錄初始化中不完全踩坑指南1.項目改造
安裝所需的插件
npm install vue-property-decorator vuex-class --save
npm install ts-loader typescript typescript-eslint-parser --save-dev
- vuex-class:ts版的vuex插件
- ts-loader: webpack插件- typescript: 必備插件- typescript-eslint-parser: eslint解析ts插件2.WebPack配置修改
webpac.conf中添加ts的解析module
extensions中添加ts結尾的文件
entry: { app: ./src/main.ts},// ....extensions: [.js, .vue, .json, .ts],// ....{ test: /.ts$/, loader: ts-loader, exclude: /node_modules/, options: { appendTsSuffixTo: [/.vue$/], }}
3.添加tsconfig.json、d.ts文件,修改eslint
修改eslint解析規則為ts
// ...parserOptions: { parser: typescript-eslint-parser},// ... plugins: [ vue, typescript],
在.eslintrc.js同級目錄創建tsconfig.json文件
{ "include": [ "src/*", "src/**/*" ], "exclude": [ "node_modules" ], "compilerOptions": { // types option has been previously configured "types": [ // add node as an option "node" ], // typeRoots option has been previously configured "typeRoots": [ // add path to @types "node_modules/@types" ], // 以嚴格模式解析 "strict": true, "strictPropertyInitialization": false, // 在.tsx文件里支持JSX "jsx": "preserve", // 使用的JSX工廠函數 "jsxFactory": "h", // 允許從沒有設置默認導出的模塊中默認導入 "allowSyntheticDefaultImports": true, // 啟用裝飾器 "experimentalDecorators": true, "strictFunctionTypes": false, // 允許編譯javascript文件 "allowJs": true, // 採用的模塊系統 "module": "esnext", // 編譯輸出目標 ES 版本 "target": "es5", // 如何處理模塊 "moduleResolution": "node", // 在表達式和聲明上有隱含的any類型時報錯 "noImplicitAny": true, "lib": [ "dom", "es5", "es6", "es7", "es2015.promise" ], "sourceMap": true, "pretty": true }}
在src目錄下添加/typings/vue-shims.d.ts,聲明所有的.vue文件
declare module "*.vue" { import Vue from "vue"; export default Vue;}
4.對原有文件進行改造
/src/router/index.ts
import Vue, { AsyncComponent } from vueimport Router, { RouteConfig, Route, NavigationGuard } from vue-routerconst Home: AsyncComponent = (): any => import(@/views/Home/index.vue)Vue.use(Router)const routes: RouteConfig[] = [ { path: /, name: Home, component: Home }]const router: Router = new Router({ mode: history, base: /, routes})export default router
/src/store
index.tsimport Vue from vueimport Vuex, {ActionTree, MutationTree} from vueximport actions from ./actionsimport mutations from ./mutations;import getters from ./gettersVue.use(Vuex)interface State { token: string, login: Boolean,}let state: State = { token: token, login: false}export default new Vuex.Store({ state, getters, mutations, actions})
mutations.ts
import TYPES from ./typesimport { MutationTree } from vuexconst mutations: MutationTree<any> = { [TYPES.SET_TOKEN](state, token): void{ state.token = token }}export default mutations
actions.ts
import { ActionTree } from vueximport TYPES from ./typesconst actions: ActionTree<any, any> = { initToken({commit}, token: string) { commit(TYPES.SET_TOKEN, token) }}
export default actions
/src/main.ts
import Vue from vue;import App from ./App.vue;import store from ./storeimport router from ./router;Vue.config.productionTip = falsenew Vue({ el: #app, router, store, components: { App }, template: <App/>})
5.vue-property-decorator使用
vue-property-decorator基於vue-class-component封裝
提供了7種方法import {Emit, Inject, Model, Prop, Provide, Watch, Componet}
<script lang="ts">import Vue from vueimport {Component, Prop, Emit} from vue-property-decoratorinterface List { title: string, imgSrc: string, url?: string}@Component({ name: HomeBlock, component: { // 這裡註冊組件 }})export default class HomeBlock extends Vue { @Prop({default: []}) dataList: List[] // 等同於 // props: { // dataList: { // default: [], // type: Array // } //} @Emit(jump) jumpRoute(url: string){ // ... } // 等同於 // jumpRoute(url) { // this.$emit(jump, url) // } @Watch(child) onChildChanged(val: string, oldVal: string) { } // 等同於 // watch: { // child: { // handler: onChildChanged, // immediate: false, // deep: false // }, // } mounted() { console.log(this.dataList) }}</script>
錯誤匯總
- typescript版本過新為3.1.x的情況會提示無法找到vue-loader,需要降級到2.8.x
- TS2564:Property xx has no initializer and in not definitely assigned in constructor在ts新版本中加入的,屬性初始化可能為undefined的情況需要考慮進去解決方案1,在定義的時候例如 url: string | undefined (不太清楚方法要怎麼定義,ts不太熟)解決方案2,在tsconfig的compilerOptions中 添加
"strictPropertyInitialization": false,
推薦閱讀:
※如何進一步熟悉甚至掌握Angular?
※【認真臉】註解與裝飾器的點點滴滴
※ThinkJS 3.0 如何實現對 TypeScript 的支持
※現在 TypeScript 的生態如何?
※基於 Immutable.js 實現撤銷重做功能
TAG:TypeScript | Vuejs |