1. 程式人生 > >Vue.js TypeScript 支援

Vue.js TypeScript 支援

TypeScript 支援

在 Vue 2.5.0 中,我們大大改進了型別宣告以更好地使用預設的基於物件的 API。同時此版本也引入了一些其它變化,需要開發者作出相應的升級。閱讀部落格文章瞭解更多詳情。

釋出為 NPM 包的官方宣告檔案

靜態型別系統能幫助你有效防止許多潛在的執行時錯誤,而且隨著你的應用日漸豐滿會更加顯著。這就是為什麼 Vue 不僅僅為 Vue core 提供了針對 TypeScript 的官方型別宣告,還為 Vue Router 和 Vuex 也提供了相應的宣告檔案。

而且,我們已經把它們釋出到了 NPM

,最新版本的 TypeScript 也知道該如何自己從 NPM 包裡解析型別宣告。這意味著只要你成功地通過 NPM 安裝了,就不再需要任何額外的工具輔助,即可在 Vue 中使用 TypeScript 了。

推薦配置

// tsconfig.json
{
  "compilerOptions": {
    // 與 Vue 的瀏覽器支援保持一致
    "target": "es5",
    // 這可以對 `this` 上的資料屬性進行更嚴格的推斷
    "strict": true,
    // 如果使用 webpack 2+ 或 rollup,可以利用 tree-shake:
    "module": "es2015",
    "moduleResolution": "node"
  }
}

注意你需要引入 strict: true (或者至少 noImplicitThis: true,這是 strict模式的一部分) 以利用元件方法中 this 的型別檢查,否則它會始終被看作 any 型別。

參閱 TypeScript 編譯器選項文件 (英) 瞭解更多。

開發工具鏈

工程建立

Vue CLI 3 可以使用 TypeScript 生成新工程。建立方式:

# 1. 如果沒有安裝 Vue CLI 就先安裝
npm install --global @vue/cli

# 2. 建立一個新工程,並選擇 "Manually select features (手動選擇特性)" 選項
vue create my-project-name

編輯器支援

要使用 TypeScript 開發 Vue 應用程式,我們強烈建議您使用 Visual Studio Code,它為 TypeScript 提供了極好的“開箱即用”支援。如果你正在使用單檔案元件 (SFC), 可以安裝提供 SFC 支援以及其他更多實用功能的 Vetur 外掛

WebStorm 同樣為 TypeScript 和 Vue 提供了“開箱即用”的支援。

基本用法

要讓 TypeScript 正確推斷 Vue 元件選項中的型別,您需要使用 Vue.component 或 Vue.extend 定義元件:

import Vue from 'vue'
const Component = Vue.extend({
  // 型別推斷已啟用
})

const Component = {
  // 這裡不會有型別推斷,
  // 因為TypeScript不能確認這是Vue元件的選項
}

基於類的 Vue 元件

如果您在宣告元件時更喜歡基於類的 API,則可以使用官方維護的 vue-class-component 裝飾器:

import Vue from 'vue'
import Component from 'vue-class-component'

// @Component 修飾符註明了此類為一個 Vue 元件
@Component({
  // 所有的元件選項都可以放在這裡
  template: '<button @click="onClick">Click!</button>'
})
export default class MyComponent extends Vue {
  // 初始資料可以直接宣告為例項的屬性
  message: string = 'Hello!'

  // 元件方法也可以直接宣告為例項的方法
  onClick (): void {
    window.alert(this.message)
  }
}

增強型別以配合外掛使用

外掛可以增加 Vue 的全域性/例項屬性和元件選項。在這些情況下,在 TypeScript 中製作外掛需要型別宣告。慶幸的是,TypeScript 有一個特性來補充現有的型別,叫做模組補充 (module augmentation)

例如,宣告一個 string 型別的例項屬性 $myProperty

// 1. 確保在宣告補充的型別之前匯入 'vue'
import Vue from 'vue'

// 2. 定製一個檔案,設定你想要補充的型別
//    在 types/vue.d.ts 裡 Vue 有建構函式型別
declare module 'vue/types/vue' {
// 3. 宣告為 Vue 補充的東西
  interface Vue {
    $myProperty: string
  }
}

在你的專案中包含了上述作為宣告檔案的程式碼之後 (像 my-property.d.ts),你就可以在 Vue 例項上使用 $myProperty 了。

var vm = new Vue()
console.log(vm.$myProperty) // 將會順利編譯通過

你也可以宣告額外的屬性和元件選項:

import Vue from 'vue'

declare module 'vue/types/vue' {
  // 可以使用 `VueConstructor` 介面
  // 來宣告全域性屬性
  interface VueConstructor {
    $myGlobal: string
  }
}

// ComponentOptions 聲明於 types/options.d.ts 之中
declare module 'vue/types/options' {
  interface ComponentOptions<V extends Vue> {
    myOption?: string
  }
}

上述的宣告允許下面的程式碼順利編譯通過:

// 全域性屬性
console.log(Vue.$myGlobal)

// 額外的元件選項
var vm = new Vue({
  myOption: 'Hello'
})

標註返回值

因為 Vue 的宣告檔案天生就具有迴圈性,TypeScript 可能在推斷某個方法的型別的時候存在困難。因此,你可能需要在 render 或 computed 裡的方法上標註返回值。

import Vue, { VNode } from 'vue'

const Component = Vue.extend({
  data () {
    return {
      msg: 'Hello'
    }
  },
  methods: {
    // 需要標註有 `this` 參與運算的返回值型別
    greet (): string {
      return this.msg + ' world'
    }
  },
  computed: {
    // 需要標註
    greeting(): string {
      return this.greet() + '!'
    }
  },
  // `createElement` 是可推導的,但是 `render` 需要返回值型別
  render (createElement): VNode {
    return createElement('div', this.greeting)
  }
})

如果你發現型別推導或成員補齊不工作了,標註某個方法也許可以幫助你解決這個問題。使用 --noImplicitAny 選項將會幫助你找到這些未標註的方法。

from: https://cn.vuejs.org/v2/guide/typescript.html