Vue 3.0 TypeScript支持

2021-07-16 11:44 更新

Vue CLI 提供內置的 TypeScript 工具支持。

#NPM 包中的官方聲明

隨著應用的增長,靜態(tài)類型系統可以幫助防止許多潛在的運行時錯誤,這就是為什么 Vue 3 是用 TypeScript 編寫的。這意味著在 Vue 中使用 TypeScript 不需要任何其他工具——它具有一流的公民支持。

#推薦配置

  1. // tsconfig.json
  2. {
  3. "compilerOptions": {
  4. "target": "esnext",
  5. "module": "esnext",
  6. // 這樣就可以對 `this` 上的數據屬性進行更嚴格的推斷`
  7. "strict": true,
  8. "jsx": "preserve",
  9. "moduleResolution": "node"
  10. }
  11. }

請注意,必須包含 strict: true (或至少包含 noImplicitThis: true,它是 strict 標志的一部分) 才能在組件方法中利用 this 的類型檢查,否則它總是被視為 any 類型。

參見 TypeScript 編譯選項文檔查看更多細節(jié)。

#開發(fā)工具

#項目創(chuàng)建

Vue CLI 可以生成使用 TypeScript 的新項目,開始:

  1. ## 1. Install Vue CLI, 如果尚未安裝
  2. npm install --global @vue/cli@next
  3. ## 2. 創(chuàng)建一個新項目, 選擇 "Manually select features" 選項
  4. vue create my-project-name
  5. ## 3. 如果已經有一個不存在TypeScript的 Vue CLI項目,請?zhí)砑舆m當的 Vue CLI插件:
  6. vue add typescript

請確保組件的 script 部分已將語言設置為 TypeScript:

  1. <script lang="ts">
  2. ...
  3. </script>

#編輯器支持

對于使用 TypeScript 開發(fā) Vue 應用程序,我們強烈建議使用 Visual Studio Code,它為 TypeScript 提供了很好的開箱即用支持。如果你使用的是單文件組件 (SFCs),那么可以使用很棒的 Vetur extension,它在 SFCs 中提供了 TypeScript 推理和許多其他優(yōu)秀的特性。

WebStorm 還為 TypeScript 和 Vue 提供現成的支持。

#定義 Vue 組件

要讓 TypeScript 正確推斷 Vue 組件選項中的類型,需要使用 defineComponent 全局方法定義組件:

  1. import { defineComponent } from 'vue'
  2. const Component = defineComponent({
  3. // 已啟用類型推斷
  4. })

#與 Options API 一起使用

TypeScript 應該能夠在不顯式定義類型的情況下推斷大多數類型。例如,如果有一個具有數字 count property 的組件,如果試圖對其調用特定于字符串的方法,則會出現錯誤:

  1. const Component = defineComponent({
  2. data() {
  3. return {
  4. count: 0
  5. }
  6. },
  7. mounted() {
  8. const result = this.count.split('') // => Property 'split' does not exist on type 'number'
  9. }
  10. })

如果你有一個復雜的類型或接口,你可以使用 type assertion 對其進行強制轉換:

  1. interface Book {
  2. title: string
  3. author: string
  4. year: number
  5. }
  6. const Component = defineComponent({
  7. data() {
  8. return {
  9. book: {
  10. title: 'Vue 3 Guide',
  11. author: 'Vue Team',
  12. year: 2020
  13. } as Book
  14. }
  15. }
  16. })

#注釋返回類型

由于 Vue 聲明文件的循環(huán)特性,TypeScript 可能難以推斷 computed 的類型。因此,你可能需要注釋返回類型的計算屬性。

  1. import { defineComponent } from 'vue'
  2. const Component = defineComponent({
  3. data() {
  4. return {
  5. message: 'Hello!'
  6. }
  7. },
  8. computed: {
  9. // 需要注釋
  10. greeting(): string {
  11. return this.message + '!'
  12. }
  13. // 在使用setter進行計算時,需要對getter進行注釋
  14. greetingUppercased: {
  15. get(): string {
  16. return this.greeting.toUpperCase();
  17. },
  18. set(newValue: string) {
  19. this.message = newValue.toUpperCase();
  20. },
  21. },
  22. }
  23. })

#注釋 Props

Vue 對定義了 type 的 prop 執(zhí)行運行時驗證。要將這些類型提供給 TypeScript,我們需要使用 PropType 強制轉換構造函數:

  1. import { defineComponent, PropType } from 'vue'
  2. interface ComplexMessage {
  3. title: string
  4. okMessage: string
  5. cancelMessage: string
  6. }
  7. const Component = defineComponent({
  8. props: {
  9. name: String,
  10. success: { type: String },
  11. callback: {
  12. type: Function as PropType<() => void>
  13. },
  14. message: {
  15. type: Object as PropType<ComplexMessage>,
  16. required: true,
  17. validator(message: ComplexMessage) {
  18. return !!message.title
  19. }
  20. }
  21. }
  22. })

如果你發(fā)現驗證器沒有得到類型推斷或者成員完成不起作用,那么用期望的類型注釋參數可能有助于解決這些問題。

#與組合式 API 一起使用

setup() 函數中,不需要將類型傳遞給 props 參數,因為它將從 props 組件選項推斷類型。

  1. import { defineComponent } from 'vue'
  2. const Component = defineComponent({
  3. props: {
  4. message: {
  5. type: String,
  6. required: true
  7. }
  8. },
  9. setup(props) {
  10. const result = props.message.split('') // 正確, 'message' 被聲明為字符串
  11. const filtered = props.message.filter(p => p.value) // 將引發(fā)錯誤: Property 'filter' does not exist on type 'string'
  12. }
  13. })

#類型聲明 ref

Refs 根據初始值推斷類型:

  1. import { defineComponent, ref } from 'vue'
  2. const Component = defineComponent({
  3. setup() {
  4. const year = ref(2020)
  5. const result = year.value.split('') // => Property 'split' does not exist on type 'number'
  6. }
  7. })

有時我們可能需要為 ref 的內部值指定復雜類型。我們可以在調用 ref 重寫默認推理時簡單地傳遞一個泛型參數:

  1. const year = ref<string | number>('2020') // year's type: Ref<string | number>
  2. year.value = 2020 // ok!

TIP

如果泛型的類型未知,建議將 ref 轉換為 Ref<T>

#類型聲明 reactive

當聲明類型 reactive property,我們可以使用接口:

  1. import { defineComponent, reactive } from 'vue'
  2. interface Book {
  3. title: string
  4. year?: number
  5. }
  6. export default defineComponent({
  7. name: 'HelloWorld',
  8. setup() {
  9. const book = reactive<Book>({ title: 'Vue 3 Guide' })
  10. // or
  11. const book: Book = reactive({ title: 'Vue 3 Guide' })
  12. // or
  13. const book = reactive({ title: 'Vue 3 Guide' }) as Book
  14. }
  15. })

#類型聲明 computed

計算值將根據返回值自動推斷類型

  1. import { defineComponent, ref, computed } from 'vue'
  2. export default defineComponent({
  3. name: 'CounterButton',
  4. setup() {
  5. let count = ref(0)
  6. // 只讀
  7. const doubleCount = computed(() => count.value * 2)
  8. const result = doubleCount.value.split('') // => Property 'split' does not exist on type 'number'
  9. }
  10. })
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號