更新於 2024/11/01閱讀時間約 13 分鐘

EP55 - 使用TypeScript來開發Vue

Using Vue with TypeScript,很久以前就聽過TypeScript了
接下來三篇內容會介紹TypeScript如何開發Vue的狀況吧?
快來看看吧~

像 TypeScript 這樣的類型系統可以通過靜態分析在構建時檢測許多常見錯誤。這減少了在生產環境中出現運行時錯誤的機會,也使我們在大型應用程序中更有信心地進行代碼重構。TypeScript 還通過在集成開發環境 (IDE) 中基於類型的自動完成來改善開發者的使用體驗。

Vue 本身就是用 TypeScript 編寫的,並提供了原生的 TypeScript 支持。所有官方的 Vue 套件都包含了開箱即用的類型聲明。

專案設置 - Project Setup

create-vue,官方的專案腳手架工具,提供了搭建基於 Vite 的 TypeScript 準備好的 Vue 專案的選項。

概覽 - Overview

使用基於 Vite 的設置,開發伺服器和打包器僅進行轉譯,並不進行類型檢查。這確保了即使在使用 TypeScript 的情況下,Vite 開發伺服器仍能保持極快的速度。

  • 在開發過程中,我們建議依賴良好的 IDE 設置來即時反饋類型錯誤。
  • 如果使用單文件組件 (SFC),請使用 vue-tsc 工具進行命令行類型檢查和類型聲明生成。vue-tsc 是 TypeScript 自身命令行介面的包裝器。它的工作方式基本與 tsc 相同,除了它除了支援 TypeScript 文件外,還支援 Vue SFC。您可以在 Vite 開發伺服器運行的同時以監視模式運行 vue-tsc,或者使用像 vite-plugin-checker 的 Vite 插件,該插件在單獨的工作線程中運行檢查。
  • Vue CLI 也提供 TypeScript 支持,但不再建議使用。請參見下面的說明

IDE 支持 - IDE Support

強烈建議使用 Visual Studio Code (VS Code),因為它對 TypeScript 提供了極好的開箱即用支持。

  • Vue - Official(之前的 Volar)是官方的 VS Code 擴展,提供在 Vue SFC 中的 TypeScript 支持,還有許多其他優秀的功能。
提示: Vue - Official 擴展取代了 Vetur,我們之前的官方 VS Code 擴展,適用於 Vue 2。如果您當前在 Vue 3 專案中安裝了 Vetur,請確保在 Vue 3 專案中禁用它。
  • WebStorm 也提供對 TypeScript 和 Vue 的開箱即用支持。其他 JetBrains 的 IDE 也支持它們,無論是開箱即用還是通過免費插件。從 2023.2 版本開始,WebStorm 和 Vue 插件內置支持 Vue 語言伺服器。您可以在設置 > 語言和框架 > TypeScript > Vue 下設置 Vue 服務以使用 Volar 整合,默認情況下,Volar 將用於 TypeScript 版本 5.0 及更高版本。

配置 tsconfig.json - Configuring tsconfig.json

通過 create-vue 建立的專案包括預配置的 tsconfig.json。基礎配置在 @vue/tsconfig 包中進行抽象。在專案中,我們使用專案引用來確保在不同環境中運行的代碼具有正確的類型(例如,應用代碼和測試代碼應有不同的全局變量)。

手動配置 tsconfig.json 時,一些值得注意的選項包括:

  • compilerOptions.isolatedModules 設置為 true,因為 Vite 使用 esbuild 來轉譯 TypeScript,並受單檔轉譯的限制。compilerOptions.verbatimModuleSyntax 是 isolatedModules 的超集,也是良好的選擇 - 這是 @vue/tsconfig 使用的設置。
  • 如果您使用選項 API,則需要將 compilerOptions.strict 設置為 true(或至少啟用 compilerOptions.noImplicitThis,這是嚴格標誌的一部分),以利用組件選項中的類型檢查。否則,這將被視為 any。
  • 如果您在構建工具中配置了解析器別名,例如在 create-vue 專案中默認配置的 @/* 別名,您還需要通過 compilerOptions.paths 為 TypeScript 配置它。
  • 如果您打算在 Vue 中使用 TSX,請將 compilerOptions.jsx 設置為 "preserve",並將 compilerOptions.jsxImportSource 設置為 "vue"。

另請參見:

注意事項關於 Vue CLI 和 ts-loader的說明 - Note on Vue CLI and ts-loader

在基於 webpack 的設置(例如 Vue CLI)中,通常在模組轉換管道中執行類型檢查,例如使用 ts-loader。然而,這並不是一個乾淨的解決方案,因為類型系統需要了解整個模組圖以進行類型檢查。單個模組的轉換步驟根本不適合這項任務。這會導致以下問題:

  • ts-loader 僅能檢查轉換後的代碼類型。這與我們在 IDE 或 vue-tsc 中看到的錯誤不一致,後者直接映射回源代碼。
  • 類型檢查可能會很慢。當它與代碼轉換在同一線程/進程中執行時,會顯著影響整個應用程序的構建速度。
  • 我們已經在 IDE 中以單獨進程運行類型檢查,因此開發體驗的延遲成本並不是一個好的交易。

如果您目前正在通過 Vue CLI 使用 Vue 3 + TypeScript,我們強烈建議遷移到 Vite。我們也在努力提供 CLI 選項以啟用僅轉譯的 TS 支持,這樣您就可以切換到 vue-tsc 進行類型檢查。

一般使用注意事項 - General Usage Notes

defineComponent()

為了讓 TypeScript 正確推斷組件選項中的類型,我們需要使用 defineComponent() 定義組件:

import { defineComponent } from 'vue'

export default defineComponent({
// 啟用類型推斷
props: {
name: String,
msg: { type: String, required: true }
},
data() {
return {
count: 1
}
},
mounted() {
this.name // 類型:string | undefined
this.msg // 類型:string
this.count // 類型:number
}
})

defineComponent() 也支援在使用組合式 API 而不使用 <script setup> 時推斷傳遞給 setup() 的 props:

import { defineComponent } from 'vue'

export default defineComponent({
// 啟用類型推斷
props: {
message: String
},
setup(props) {
props.message // 類型:string | undefined
}
})

另請參見:

提示: defineComponent() 也啟用在純 JavaScript 中定義的組件的類型推斷。

在單文件組件中的使用 - Usage in Single-File Components

要在 SFC 中使用 TypeScript,請在 <script> 標籤中添加 lang="ts" 屬性。當 lang="ts" 存在時,所有模板表達式也將享受更嚴格的類型檢查。

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
data() {
return {
count: 1
}
}
})
</script>

<template>
<!-- 啟用類型檢查和自動完成功能 -->
{{ count.toFixed(2) }}
</template>

lang="ts" 也可以與 <script setup> 一起使用:

<script setup lang="ts">
// 啟用 TypeScript
import { ref } from 'vue'

const count = ref(1)
</script>

<template>
<!-- 啟用類型檢查和自動完成功能 -->
{{ count.toFixed(2) }}
</template>

模板中的 TypeScript - TypeScript in Templates

當使用 <script lang="ts"> 或 <script setup lang="ts"> 時,<template> 也支持綁定表達式中的 TypeScript。這在需要在模板表達式中進行類型轉換的情況下非常有用。

這是一個牽強的例子:

<script setup lang="ts">
let x: string | number = 1
</script>

<template>
<!-- 錯誤,因為 x 可能是字符串 -->
{{ x.toFixed(2) }}
</template>

這可以通過內聯類型轉換來解決:

<script setup lang="ts">
let x: string | number = 1
</script>

<template>
{{ (x as number).toFixed(2) }}
</template>
提示: 如果使用 Vue CLI 或基於 webpack 的設置,模板表達式中的 TypeScript 需要 vue-loader@^16.8.0。

與 TSX 的使用 - Usage with TSX

Vue 也支持使用 JSX / TSX 編寫組件。詳細內容可參見渲染函數與 JSX 指南。

泛型組件 - Generic Components

泛型組件在兩種情況下得到支持:

特定 API 範例 - API-Specific Recipes

怎麼看完有種空虛的感覺www
還是太菜沒有抓到什麼重點
所以以下問題來了!

所以TypeScript開發vue有什麼好處?

使用 TypeScript 開發 Vue 的好處包括:

  1. 靜態類型檢查:TypeScript 能夠在編譯時檢測許多常見錯誤,減少生產環境中的運行時錯誤。
  2. 更安全的重構:在大型應用中,TypeScript 提供更高的代碼重構信心,因為類型系統能夠幫助確認改動不會破壞現有功能。
  3. 更好的開發體驗:使用 TypeScript 的 IDE 提供類型基於的自動完成功能,提升開發效率。
  4. 原生支持:Vue 是用 TypeScript 開發的,並提供第一級的 TypeScript 支持,官方包含類型聲明,使用起來更方便。
  5. 改善的可維護性:透過明確的類型定義,代碼更加易讀,便於後續維護。

這些優勢使得使用 TypeScript 開發 Vue 應用變得更加高效與可靠。


分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.