Vue 3 Composition API 實戰前瞻

<code>雖然 Vue3.0 尚未發佈,但前段時間,Vue 發佈了關於 Composition API 的官方插件,使廣大用戶可以在  

Vue2.x 中享受 Function Base 帶來的新體驗。本文作者通過實際試用,對 Composition API 與當前的
Options API 作出了一番對比,並對 Composition API 的特徵與用途進行了通俗易懂的總結。一起來看看!/<code>

我最近得到了機會,在一個真實的項目中試用了 Vue 中全新的 Composition API ,進而對它可能的用途以及未來的用法探索了一番。

現在,當我們創建一個新組件時使用的是 Options API 。使用這個 API 時,我們必須通過選項將組件的代碼分離開來,這意味著我們需要將所有響應性數據放在一個地方,所有計算的屬性放在一個位置,所有方法也都放在一個位置,依此類推。

這個 API 在處理較小的組件時比較易讀和順手,而當組件變得更加複雜,需要處理多種功能時,它用起來就很痛苦了。一般來說,與一個特定功能相關的邏輯會包含一些響應性數據、一些計算屬性,還有一種或一些方法。有時還會用到組件生命週期 hooks。於是在處理單個邏輯問題時,需要不斷在代碼中的不同選項之間來回切換。

使用 Vue 時,可能遇到的另一個問題是設法提取可被多個組件複用的通用邏輯。Vue 已經提供了一些方案可供選擇,但它們都有各自的缺點(例如 mixins 和作用域插槽)。而新的 Composition API 帶來了一種創建組件、分離代碼和提取可複用代碼段的全新方式。

首先來看組件內的代碼構成。

代碼構成

假設你有一個核心組件,為整個 Vue 應用設置了一些內容(就像 Nuxt 中的佈局)。它負責處理以下內容:

  • 設定區域;
  • 檢查用戶是否處於登錄狀態,如果沒有,則將其重定向;
  • 防止用戶重新加載應用程序太多次數;
  • 跟蹤用戶活動,並在用戶靜默一段時間後做出反應;
  • 使用 EventBus 監聽事件(或窗口對象事件)。

這些只是這個組件可以做的事情的一些例子。你可能會設想出一個更復雜的組件,不過這裡的這些已經足夠本文舉例說明了。為了便於閱讀,我只用了 props 的名稱,而沒有實際實現。

下面是使用 Options API 時組件的樣子:

<code><template>

...


/<template>

/<code>

由此可見,解開這團亂麻有多複雜。

現在假設你需要更改一種功能(例如活動追蹤邏輯)。你不僅需要知道有哪些元素與該邏輯相關,而且就算你知道了,也需要在不同的組件選項之間跳來跳去。

下面我們使用 Composition API,通過邏輯關注點來分離代碼。為此,我們為每個與特定功能相關的邏輯創建一個函數。這就是我們所說的 composition 函數。

<code>// Activity tracking logic
function useActivityTracker() {
const userActivityTimeout = ref(null)
const lastUserActivityAt = ref(null)

function activateActivityTracker() {...}
function deactivateActivityTracker() {...}
function resetActivityTimeout() {...}
function userActivityThrottler() {...}

onBeforeMount(() => {
activateActivityTracker()
resetActivityTimeout()
})

onUnmounted(() => {
deactivateActivityTracker()
clearTimeout(userActivityTimeout.value)
})
}/<code>
<code>// Reload blocking logic 

function useReloadBlocker(context) {
const reloadCount = ref(null)

function blockReload() {...}
function setReloadCount() {...}

onMounted(() => {
setReloadCount()
blockReload()
})
}/<code>
<code>// Locale logic
function useLocale(context) {
async function loadLocaleAsync(selectedLocale) {...}
function setI18nLocale(locale) {...}

watch(() => {
const locale = ...
loadLocaleAsync(locale)
})

// No need for a 'created' hook, all logic that runs in setup function is placed between beforeCreate and created hooks
const initialLocale = localStorage.getItem('locale')
loadLocaleAsync(initialLocale)
}/<code>

如你所見,我們可以聲明響應性數據(ref/reactive)、計算的 props、方法(純函數)、觀察者(watch)和生命週期 hooks(onMounted/onUnmount)。基本上你平時在組件中使用的所有內容都能聲明。

關於保存代碼的位置,我們有兩個選擇。我們可以將其保留在組件中,或提取到單獨的文件中。由於 Composition API 尚未正式發佈,因此還沒有關於如何使用它的最佳實踐或規則。我的看法是,如果邏輯與特定組件緊密耦合(即不會在其他任何地方複用),並且邏輯離開了組件就無法生存,我建議將其保留在組件中。另一方面,如果是可能會被複用的一般性功能,則建議將其提取到單獨的文件中。但如果我們要將其保存在單獨的文件中,則需要從文件中導出函數並將其導入到組件中。

這是使用新創建的 composition 函數後,我們組件的樣子:

<code><template>



/<template>

/<code>

這裡每個邏輯關注點都有了一個函數。如果要使用某一個關注點,則需要在新的 setup 函數中調用相關的 composition 函數。

再設想一下,你需要對活動跟蹤邏輯作一些更改。與該功能相關的所有內容都放在 useActivityTracker 函數中。現在你就能立刻找出並跳轉到正確的位置,查看所有相關的代碼段了。非常漂亮!

提取可複用的代碼段

在我們的例子中,事件總線偵聽器註冊(Event Bus listener registrations)看來是一段代碼,如果有組件需要偵聽事件總線上的事件,我們就可以用這段代碼來實現。

如前所述,我們可以將與特定功能相關的邏輯保存在單獨的文件中。下面我們將事件總線偵聽器設置轉移到一個單獨的文件中。

<code>// composables/useEventBusListener.js 

import EventBus from '@/event-bus'

export function useEventBusListener(eventName, handler) {
onMounted(() => EventBus.$on(eventName, handler))
onUnmounted(() => EventBus.$off(eventName, handler))
}/<code>

要在組件中使用它,我們需要導出函數(命名或默認),並將其導入組件中。

<code><template>

...

/<template>

/<code>

完事了!現在我們能在任何組件中使用它了。

小 結

關於 Composition API 的討論還在進行中。這篇文章無意在討論中站隊,更關心的是新 API 可能的用途,以及它能在哪些情況下帶來附加價值。

我認為在現實案例中理解概念總是比較容易的,就像上面這個例子一樣。用例越多,使用新 API 的次數越多,我們也就能發現更多的模式。這篇文章只涉及了一些基本的模式,供拋磚引玉。

我們再來看一遍上面這些用例,看看 Composition API 的用途有哪些:

1. 無需與任何特定組件緊密耦合也能獨立運行的一般性功能

  • 與一個特定功能相關的所有邏輯都放在一個文件中;
  • 將其保存在 @/composables/*.js,並將其導入組件中;
  • 示例:活動跟蹤、阻止重新加載和區域設置。

2. 可在多個組件中使用的可複用功能

  • 與一個特定功能相關的所有邏輯都放在一個文件中;
  • 將其保存在 @/composables/*.js,並將其導入組件中;
  • 示例:事件總線偵聽器註冊、窗口事件註冊、通用動畫邏輯、通用庫的使用。

3. 組件內的代碼組織

  • 與一個特定功能相關的所有邏輯都放在一個函數中;
  • 將代碼保留在組件內的 composition 函數中;
  • 與同一邏輯關注點相關的代碼位於同一位置。也就是說,無需在數據、計算屬性、方法、生命週期 hooks 等內容之間來回跳轉)。

記住:這些都尚在開發中!

Vue Composition API 目前尚處於開發階段,未來還可能出現更改。上面示例中提到的任何內容、語法和用例都可能出現變化。這個 API 計劃將隨 Vue 3.0 一起推出。另外,你可以在 view-use-web 上查看一組 composition 函數的信息,這些函數預計會包含在 Vue 3 中,但也能用在 Vue 2 中的 Composition API 上。

如果你想嘗試新的 API,可以使用 @vue/composition 庫。


Vue 3 Composition API 實戰前瞻


分享到:


相關文章: