vue+Typescript初級入門

Typescript 在前端圈已經逐漸普及,Vue 2.5.0 改進了類型聲明,使得對 TypeScript 更加友好

不過要想在項目中直接使用 TypeScript  仍然須要對項目進行一些改造

PS: 建議使用  Visual Studio Code 進行開發

 

vue-cli 3.0 能夠直接建立 typescript 項目,不過目前還只有 beta 版,有興趣的朋友能夠嘗試一下

 

1、安裝依賴

首先仍是用 vue-cli 生成項目

vue init webpack demo
而後安裝必要依賴項:typescript、ts-loader、vue-class-component

npm install typescript vue-class-component -D
npm install ts-loader@3.3.1 -D
上面安裝 ts-loader 的時候,指定了版本 3.3.1

這是由於在寫這篇博客的時候(2018-03-14),在安裝 ts-loader 的最新版 4.0.1 的狀況下,啓動項目會報錯

 

另外還有幾個庫能夠按需引入:

tslint: 規範 ts 代碼,須要配合 tsllint-loader 使用,最好再加上 tslint-config-standard;

vue-property-decorator:  vue-class-component 的擴展,添加了幾個結合 Vue 特性的裝飾器(@Emit,@Prop 等);

vuex-class: 在 vue-class-component 基礎上增強了對 vuex 的支持。

 

2、配置 Webpack

而後修改 ./build/webpack.base.conf.js 文件:



在 resolve.extension 中添加 ‘.ts’,使引入 ts 文件時不用寫 .ts 後綴

 



複製代碼
{
  test: /\.tsx?$/,
  loader: 'ts-loader',
  exclude: /node_modules/,
  options: {
    appendTsSuffixTo: [/\.vue$/]
  }
}
複製代碼
在 module.rules 中添加 webpack 對 ts 文件的解析

 

3、其餘配置

在項目根目錄下建立 tsconfig.json 文件:

複製代碼
// tsconfig.json
{
  "compilerOptions": {
    // 與 Vue 的瀏覽器支持保持一致
    "target": "es5",
    // 這能夠對 `this` 上的數據屬性進行更嚴格的推斷
    "strict": true,
    // 若是使用 webpack 2+ 或 rollup,能夠利用 tree-shake:
    "module": "es2015",
    "moduleResolution": "node"
  }
}
複製代碼
完整的 tsconfig.json 配置項能夠參考官方文檔

 

在 ./src 目錄建立 vue-shim.d.ts 文件,讓 ts 識別 .vue 文件:

// vue-shim.d.ts
declare module "*.vue" {
  import Vue from "vue";
  export default Vue;
}
 

4、文件改造

將 src 目錄下的全部 js 文件後綴改成 .ts



而後將 webpack 配置文件 ./build/webpack.base.conf.js 中的入口 entry 修改成 main.ts



 

改造以後的 ts 文件不會識別 .vue 文件,因此在引入 .vue 文件的時候,須要手動添加 .vue 後綴





 

在全部 .vue 文件中,都須要在 <script> 中添加 lang="ts" 標識

要讓 TypeScript 正確推斷 vue 組件選項中的類型,還須要引入 vue,並使用 Vue.extend 定義組件



 

至此基本改造已經完成,執行 npm run dev 就能正常啓動項目

 

5、基於類的 Vue 組件改造

上面改造 .vue 文件的時候,只是簡單的使用了 Vue.extend 方法,組件內部仍是採用原生的 vue 寫法

這在實際開發的時候並不能良好的使用 typescript 特性,因此還須要利用 vue-class-component 繼續改造

 

首先在 tsconfig.json 中添加配置項,而後重啓項目

// 容許從沒有設置默認導出的模塊中默認導入
"allowSyntheticDefaultImports": true,
// 啓用裝飾器
"experimentalDecorators": true
 

 而後改造 .vue 文件的 <script> 部分,以 HelloWorld.vue 爲例:

複製代碼
// HelloWorld.vue

<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'

// @Component 修飾符註明了此類爲一個 Vue 組件
@Component({})
export default class Hello extends Vue {
  msg: String = 'Welcome to Your Vue.js App'
}
</script>
複製代碼
 

組件內部再也不採用 Vue 的格式,一開始也許不易接受,能夠參考官方的遷移示例

複製代碼
// Vue 文件格式示範

<template>
  <div>
    <input v-model="msg">
    <p>prop: {{propMessage}}</p>
    <p>msg: {{msg}}</p>
    <p>helloMsg: {{helloMsg}}</p>
    <p>computed msg: {{computedMsg}}</p>
    <button @click="greet">Greet</button>
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
  props: {
    propMessage: String
  }
})
export default class App extends Vue {
  // initial data
  msg = 123

  // use prop values for initial data
  helloMsg = 'Hello, ' + this.propMessage

  // lifecycle hook
  mounted () {
    this.greet()
  }

  // computed
  get computedMsg () {
    return 'computed ' + this.msg
  }

  // method
  greet () {
    alert('greeting: ' + this.msg)
  }
}
</script>
複製代碼
 

6、使用TSlint 規範代碼

若是對代碼格式有着嚴格的要求,建議引入 tslint 來規範代碼,首先安裝如下依賴

npm init tslint tslint-loader tslint-config-standard -D
 

而後在 ./build/webpack.base.conf.js 的 module.rules 中添加規則



{
  test: /\.ts$/,
  exclude: /node_modules/,
  enforce: 'pre',
  loader: 'tslint-loader'
}
 

在項目根目錄建立配置文件 tslint.json

複製代碼
// tslint.json
{
  "extends": "tslint-config-standard",
  "globals": {
    "require": true
  }
}
複製代碼
 

這時已經能夠啓動項目了,若是出現了這樣的警告



只須要在 main.ts 裏面,將實例化的 Vue 賦值給一個對象就好



只是這裏的 tslint 校驗規則是直接引入的 standard 規範,若是須要自定義

貼一篇網上找的 tslint.json 的配置項說明(來源:http://blog.csdn.net/zw52yany/article/details/78688837)

複製代碼
extends: 內設配置項名稱
rules:  規則
  {
    //ts專用
    adjacent-overload-signatures : true,  //  Enforces function overloads to be consecutive.
    ban-comma-operator:true, //禁止逗號運算符。
    ban-type: [true, ["object","User {} instead."],["string"]] //禁止類型
    member-access: [true , "no-public"||"check-accessor"|| "check-constructor" || "check-parameter-property"  ] ,  //類成員必須聲明 private public ....
    member-order: [true, {order:....}],  //類聲明排序
    no-any: true,//不需使用any類型
    no-empty-interface:true //禁止空接口 {}
    no-import-side-effect: [true, {"ignore-module": "(\\.html|\\.css)$"}], //禁止導入帶有反作用的語句
    no-inferrable-types:[true, "ignore-params", "ignore-properties"], //不容許將變量或參數初始化爲數字,字符串或布爾值的顯式類型聲明。
    no-internal-module:true//不容許內部模塊
    no-magic-numbers: [true,1,2,3], //不容許在變量賦值以外使用常量數值。當沒有指定容許值列表時,默認容許-1,0和1
    no-namespace: [ true,"allpw-declarations"], //不容許使用內部modules和命名空間
    no-non-null-assertion: true , //不容許使用!後綴操做符的非空斷言。
    no-parameter-reassignment: true, //不容許從新分配參數
    no-reference: true, // 禁止使用/// <reference path=> 導入 ,使用import代替
    no-unnecessary-type-assertion: true, //若是類型斷言沒有改變表達式的類型就發出警告
    no-var-requires: true, //不容許使用var module = require("module"),用 import foo = require('foo')導入
    only-arrow-functions:[true,"allow-declarations","allow-named-functions"], //容許箭頭表達式,不須要傳統表達式 ; 容許獨立的函數聲明  ;容許表達,function foo() {}但不是function() {}
    prefer-for-of:true,  //建議使用for(..of)
    promise-function-async: true, 要求異步函數返回promise
    typedef: [true, "call-signature", "parameter", "member-variable-declaration"], //須要定義的類型存在
    typedef-whitespace: true, //類型聲明的冒號以前是否須要空格
    unified-signatures: true, //重載能夠被統一聯合成一個

    //function 專用
    await-promise: true,  //警告不是一個promise的await
    ban: [
          true,
          "eval",
          {"name": "$", "message": "please don't"},
          ["describe", "only"],
          {"name": ["it", "only"], "message": "don't focus tests"},
          {
            "name": ["chai", "assert", "equal"],
            "message": "Use 'strictEqual' instead."
          },
          {"name": ["*", "forEach"], "message": "Use a regular for loop instead."}
    ],
    curly: true, //for if do while 要有括號
    forin:true, //用for in 必須用if進行過濾
    import-blacklist:true, //容許使用import require導入具體的模塊
    label-postion: true, //容許在do/for/while/swith中使用label
    no-arg:true, //不容許使用 argument.callee
    no-bitwise:true, //不容許使用按位運算符
    no-conditional-assignmen: true, //不容許在do-while/for/if/while判斷語句中使用賦值語句
    no-console:true, //不能使用console
    no-construct: true, //不容許使用 String/Number/Boolean的構造函數
    no-debuggertrue, //不容許使用debugger
    no-duplicate-super: true, //構造函數兩次用super會發出警告
    no-empty:true, //不容許空的塊
    no-eval: true, //不容許使用eval
    no-floating-promises: true, //必須正確處理promise的返回函數
    no-for-in-array: true, //不容許使用for in 遍歷數組
    no-implicit-dependencies: true, //不容許在項目的package.json中導入未列爲依賴項的模塊
    no-inferred-empty-object-type: true//不容許在函數和構造函數中使用{}的類型推斷
    no-invalid-template-strings: true, //警告在非模板字符中使用${
    no-invalid-thistrue, //不容許在非class中使用 this關鍵字
    no-misused-new: true, //禁止定義構造函數或new class
    no-null-keyword: true, //不容許使用null關鍵字
    no-object-literal-type-assertion:true, //禁止objext出如今類型斷言表達式中
    no-return-await:true, //不容許return await
    arrow-parens: true, //箭頭函數定義的參數須要括號
  }
複製代碼
相關文章
相關標籤/搜索