TypeScript 支援
Vue CLI 提供了内建的 TypeScript 工具支持。
目录
发布为 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)
}
}
增強類型以配合插件使用
模組補充 (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
選項將會幫助你找到這些未標註的方法。