diff --git a/src/guide/extras/composition-api-faq.md b/src/guide/extras/composition-api-faq.md index e13eb569..da28af32 100644 --- a/src/guide/extras/composition-api-faq.md +++ b/src/guide/extras/composition-api-faq.md @@ -2,156 +2,156 @@ outline: deep --- -# 组合式 API 常见问答 {#composition-api-faq} +# 組合式 API 常見問答 {#composition-api-faq} :::tip -这个 FAQ 假定你已经有一些使用 Vue 的经验,特别是用选项式 API 使用 Vue 2 的经验。 +這個 FAQ 假定你已經有一些使用 Vue 的經驗,特別是在 Vue 2 使用選項式 API 的經驗。 ::: -## 什么是组合式 API? {#what-is-composition-api} +## 什麼是組合式 API? {#what-is-composition-api} - + -组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语,涵盖了以下方面的 API: +組合式 API (Composition API) 是一系列 API 的集合,使我們可以使用函數而不是聲明選項的方式書寫 Vue 組件。它是一個概括性的術語,涵蓋了以下方面的 API: -- [响应式 API](/api/reactivity-core):例如 `ref()` 和 `reactive()`,使我们可以直接创建响应式状态、计算属性和侦听器。 +- [響應式 API](/api/reactivity-core):例如 `ref()` 和 `reactive()`,使我們可以直接創建響應式狀態、計算屬性和偵聽器。 -- [生命周期钩子](/api/composition-api-lifecycle):例如 `onMounted()` 和 `onUnmounted()`,使我们可以在组件各个生命周期阶段添加逻辑。 +- [生命週期鉤子](/api/composition-api-lifecycle):例如 `onMounted()` 和 `onUnmounted()`,使我們可以在組件各個生命週期階段添加邏輯。 -- [依赖注入](/api/composition-api-dependency-injection):例如 `provide()` 和 `inject()`,使我们可以在使用响应式 API 时,利用 Vue 的依赖注入系统。 +- [依賴注入](/api/composition-api-dependency-injection):例如 `provide()` 和 `inject()`,使我們可以在使用響應式 API 時,利用 Vue 的依賴注入系統。 -组合式 API 是 Vue 3 及 [Vue 2.7](https://blog.vuejs.org/posts/vue-2-7-naruto.html) 的内置功能。对于更老的 Vue 2 版本,可以使用官方维护的插件 [`@vue/composition-api`](https://github.com/vuejs/composition-api)。在 Vue 3 中,组合式 API 基本上都会配合 [` ``` -虽然这套 API 的风格是基于函数的组合,但**组合式 API 并不是函数式编程**。组合式 API 是以 Vue 中数据可变的、细粒度的响应性系统为基础的,而函数式编程通常强调数据不可变。 +雖然這套 API 的風格是基於函數的組合,但**組合式 API 並不是函數式編程**。組合式 API 是以 Vue 中數據可變的、細粒度的響應性系統為基礎的,而函數式編程通常強調數據不可變。 -如果你对如何通过组合式 API 使用 Vue 感兴趣,可以通过页面左侧边栏上方的开关将 API 偏好切换到组合式 API,然后重新从头阅读指引。 +如果你對如何通過組合式 API 使用 Vue 感興趣,可以通過頁面左側邊欄上方的開關將 API 偏好切換到組合式 API,然後重新從頭閱讀指引。 -## 为什么要有组合式 API? {#why-composition-api} +## 為什麼要有組合式 API? {#why-composition-api} -### 更好的逻辑复用 {#better-logic-reuse} +### 更好的邏輯複用 {#better-logic-reuse} -组合式 API 最基本的优势是它使我们能够通过[组合函数](/guide/reusability/composables)来实现更加简洁高效的逻辑复用。在选项式 API 中我们主要的逻辑复用机制是 mixins,而组合式 API 解决了 [mixins 的所有缺陷](/guide/reusability/composables#vs-mixins)。 +組合式 API 最基本的優勢是它使我們能夠通過[組合函數](/guide/reusability/composables)來實現更加簡潔高效的邏輯複用。在選項式 API 中我們主要的邏輯複用機制是 mixins,而組合式 API 解決了 [mixins 的所有缺陷](/guide/reusability/composables#vs-mixins)。 -组合式 API 提供的逻辑复用能力孵化了一些非常棒的社区项目,比如 [VueUse](https://vueuse.org/),一个不断成长的工具型组合式函数集合。组合式 API 还为其他第三方状态管理库与 Vue 的响应式系统之间的集成提供了一套简洁清晰的机制,例如[不可变数据](/guide/extras/reactivity-in-depth#immutable-data)、[状态机](/guide/extras/reactivity-in-depth#state-machines)与 [RxJS](/guide/extras/reactivity-in-depth#rxjs)。 +組合式 API 提供的邏輯複用能力衍生了一些非常棒的社區項目,例如 [VueUse](https://vueuse.org/),一個不斷成長的工具型組合式函數集合。組合式 API 還為其他第三方狀態管理庫與 Vue 的響應式系統之間的集成提供了一套簡潔清晰的機制,例如[不可變數據](/guide/extras/reactivity-in-depth#immutable-data)、[狀態機](/guide/extras/reactivity-in-depth#state-machines)與 [RxJS](/guide/extras/reactivity-in-depth#rxjs)。 -### 更灵活的代码组织 {#more-flexible-code-organization} +### 更靈活的代碼組織 {#more-flexible-code-organization} -许多用户喜欢选项式 API 的原因是它在默认情况下就能够让人写出有组织的代码:大部分代码都自然地被放进了对应的选项里。然而,选项式 API 在单个组件的逻辑复杂到一定程度时,会面临一些无法忽视的限制。这些限制主要体现在需要处理多个**逻辑关注点**的组件中,这是我们在许多 Vue 2 的实际案例中所观察到的。 +許多用戶喜歡選項式 API 的原因是它在默認情況下就能夠讓人寫出有組織的代碼:大部分代碼都自然地被放進了對應的選項裡。然而,選項式 API 在單個組件的邏輯複雜到一定程度時,會面臨一些無法忽視的限制。這些限制主要體現在需要處理多個**邏輯關注點**的組件中,這是我們在許多 Vue 2 的實際案例中所觀察到的。 -我们以 Vue CLI GUI 中的文件浏览器组件为例:这个组件承担了以下几个逻辑关注点: +我們以 Vue CLI GUI 中的文件瀏覽器組件為例:這個組件承擔了以下幾個邏輯關注點: -- 追踪当前文件夹的状态,展示其内容 -- 处理文件夹的相关操作 (打开、关闭和刷新) -- 支持创建新文件夹 -- 可以切换到只展示收藏的文件夹 -- 可以开启对隐藏文件夹的展示 -- 处理当前工作目录中的变更 +- 追蹤當前文件夾的狀態,展示其內容 +- 處理文件夾的相關操作 (打開、關閉和刷新) +- 支持創建新文件夾 +- 可以切換到只展示收藏的文件夾 +- 可以開啟對隱藏文件夾的展示 +- 處理當前工作目錄中的變更 -这个组件[最原始的版本](https://github.com/vuejs/vue-cli/blob/a09407dd5b9f18ace7501ddb603b95e31d6d93c0/packages/@vue/cli-ui/src/components/folder/FolderExplorer.vue#L198-L404)是由选项式 API 写成的。如果我们为相同的逻辑关注点标上一种颜色,那将会是这样: +這個組件[最原始的版本](https://github.com/vuejs/vue-cli/blob/a09407dd5b9f18ace7501ddb603b95e31d6d93c0/packages/@vue/cli-ui/src/components/folder/FolderExplorer.vue#L198-L404)是由選項式 API 寫成的。如果我們為相同的邏輯關注點標上一種顏色,那將會是這樣: folder component before -你可以看到,处理相同逻辑关注点的代码被强制拆分在了不同的选项中,位于文件的不同部分。在一个几百行的大组件中,要读懂代码中的一个逻辑关注点,需要在文件中反复上下滚动,这并不理想。另外,如果我们想要将一个逻辑关注点抽取重构到一个可复用的工具函数中,需要从文件的多个不同部分找到所需的正确片段。 +你可以看到,處理相同邏輯關注點的代碼被強制拆分在了不同的選項中,位於文件的不同部分。在一個幾百行的大組件中,要讀懂代碼中的一個邏輯關注點,需要在文件中反覆上下滾動,這並不理想。另外,如果我們想要將一個邏輯關注點抽取重構到一個可複用的工具函數中,需要從文件的多個不同部分找到所需的正確片段。 -而如果[用组合式 API 重构](https://github.com/vuejs-translations/docs-zh-cn/blob/main/assets/FileExplorer.vue)这个组件,将会变成下面右边这样: +而如果[用組合式 API 重構](https://github.com/vuejs-translations/docs-zh-cn/blob/main/assets/FileExplorer.vue)這個組件,將會變成下面右邊這樣: -![重构后的文件夹组件](https://user-images.githubusercontent.com/499550/62783026-810e6180-ba89-11e9-8774-e7771c8095d6.png) +![重構後的文件夾組件](https://user-images.githubusercontent.com/499550/62783026-810e6180-ba89-11e9-8774-e7771c8095d6.png) -现在与同一个逻辑关注点相关的代码被归为了一组:我们无需再为了一个逻辑关注点在不同的选项块间来回滚动切换。此外,我们现在可以很轻松地将这一组代码移动到一个外部文件中,不再需要为了抽象而重新组织代码,大大降低了重构成本,这在长期维护的大型项目中非常关键。 +現在與同一個邏輯關注點相關的代碼被歸為了一組:我們無需再為了一個邏輯關注點在不同的選項塊間來回滾動切換。此外,我們現在可以很輕鬆地將這一組代碼移動到一個外部文件中,不再需要為了抽象而重新組織代碼,大大降低了重構成本,這在長期維護的大型項目中非常關鍵。 -### 更好的类型推导 {#better-type-inference} +### 更好的類型推導 {#better-type-inference} -近几年来,越来越多的开发者开始使用 [TypeScript](https://www.typescriptlang.org/) 书写更健壮可靠的代码,TypeScript 还提供了非常好的 IDE 开发支持。然而选项式 API 是在 2013 年被设计出来的,那时并没有把类型推导考虑进去,因此我们不得不做了一些[复杂到夸张的类型体操](https://github.com/vuejs/core/blob/44b95276f5c086e1d88fa3c686a5f39eb5bb7821/packages/runtime-core/src/componentPublicInstance.ts#L132-L165)才实现了对选项式 API 的类型推导。但尽管做了这么多的努力,选项式 API 的类型推导在处理 mixins 和依赖注入类型时依然不甚理想。 +近幾年來,越來越多的開發者開始使用 [TypeScript](https://www.typescriptlang.org/) 書寫更健壯可靠的代碼,TypeScript 還提供了非常好的 IDE 開發支持。然而選項式 API 是在 2013 年被設計出來的,那時並沒有把類型推導考慮進去,因此我們不得不做了一些[複雜到誇張的類型體操](https://github.com/vuejs/core/blob/44b95276f5c086e1d88fa3c686a5f39eb5bb7821/packages/runtime-core/src/componentPublicInstance.ts#L132-L165)才實現了對選項式 API 的類型推導。但儘管做了這麼多的努力,選項式 API 的類型推導在處理 mixins 和依賴注入類型時依然不甚理想。 -因此,很多想要搭配 TS 使用 Vue 的开发者采用了由 `vue-class-component` 提供的 Class API。然而,基于 Class 的 API 非常依赖 ES 装饰器,在 2019 年我们开始开发 Vue 3 时,它仍是一个仅处于 stage 2 的语言功能。我们认为基于一个不稳定的语言提案去设计框架的核心 API 风险实在太大了,因此没有继续向 Class API 的方向发展。在那之后装饰器提案果然又发生了很大的变动,在 2022 年才终于到达 stage 3。另一个问题是,基于 Class 的 API 和选项式 API 在逻辑复用和代码组织方面存在相同的限制。 +因此,很多想要搭配 TS 使用 Vue 的開發者採用了由 `vue-class-component` 提供的 Class API。然而,基於 Class 的 API 非常依賴 ES 裝飾器,在 2019 年我們開始開發 Vue 3 時,它仍是一個僅處於 stage 2 的語言功能。我們認為基於一個不穩定的語言提案去設計框架的核心 API 風險實在太大了,因此沒有繼續向 Class API 的方向發展。在那之後裝飾器提案果然又發生了很大的變動,在 2022 年才終於到達 stage 3。另一個問題是,基於 Class 的 API 和選項式 API 在邏輯複用和代碼組織方面存在相同的限制。 -相比之下,组合式 API 主要利用基本的变量和函数,它们本身就是类型友好的。用组合式 API 重写的代码可以享受到完整的类型推导,不需要书写太多类型标注。大多数时候,用 TypeScript 书写的组合式 API 代码和用 JavaScript 写都差不太多!这也让许多纯 JavaScript 用户也能从 IDE 中享受到部分类型推导功能。 +相比之下,組合式 API 主要利用基本的變量和函數,它們本身就是類型友好的。用組合式 API 重寫的代碼可以享受到完整的類型推導,不需要書寫太多類型標註。大多數時候,用 TypeScript 書寫的組合式 API 代碼和用 JavaScript 寫都差不太多!這也讓許多純 JavaScript 用戶也能從 IDE 中享受到部分類型推導功能。 -### 更小的生产包体积 {#smaller-production-bundle-and-less-overhead} +### 更小的生產包體積 {#smaller-production-bundle-and-less-overhead} -搭配 `