淺析Vue3 CompositionAPI如何替換Vue Mixins:mixin的缺點(命名沖突、隱式依賴)、CompositionAPI如何解決這些缺陷(代碼提取、代碼重用)


  想在你的Vue組件之間共享代碼?如果你熟悉 Vue 2 則可能知道使用 mixin ,但是新的 Composition API 提供了更好的解決方案。在本文中,我們將研究 mixins 的缺點,並了解 Composition API 如何克服它們,並使Vue應用程序具有更大的可伸縮性。

一、Mixins 被認為“有害”

  在了解Composition API如何克服這些缺點之前,讓我們熟悉這些缺點。

(一)命名沖突

  我們看到了mixin模式如何在運行時合並兩個對象。如果他們兩個都共享同名屬性,會發生什么?

const mixin = { data: () => ({ myProp: null }) } export default { mixins: [mixin], data: () => ({ // 同名!
    myProp: null }) }

  這就是合並策略發揮作用的地方。這是一組規則,用於確定當一個組件包含多個具有相同名稱的選項時會發生什么。

1、Vue組件的默認(但可以配置)合並策略指示本地選項將覆蓋mixin選項

2、不過也有例外,例如,如果我們有多個相同類型的生命周期鈎子,這些鈎子將被添加到一個鈎子數組中,並且所有的鈎子都將被依次調用

  盡管我們不應該遇到任何實際的錯誤,但是在跨多個組件和mixin處理命名屬性時,編寫代碼變得越來越困難。一旦第三方mixin作為帶有自己命名屬性的npm包被添加進來,就會特別困難,因為它們可能會導致沖突。

(二)隱式依賴

  mixin 和使用它的組件之間沒有層次關系。這意味着組件可以使用mixin中定義的數據屬性(例如mySharedDataProperty),但是mixin也可以使用假定在組件中定義的數據屬性(例如myLocalDataProperty)。這種情況通常是在mixin被用於共享輸入驗證時出現的,mixin可能會期望一個組件有一個輸入值,它將在自己的validate方法中使用。

  不過,這可能會引起一些問題。如果我們以后想重構一個組件,改變了mixin需要的變量的名稱,會發生什么情況呢?我們在看這個組件時,不會發現有什么問題。linter也不會發現它,我們只會在運行時看到錯誤。

  現在想象一個有很多mixin的組件。我們可以重構本地數據屬性嗎?或者它會破壞mixin嗎?我們得手動搜索才能知道。

(三)從mixins遷移

  mixin的替代方案,包括高階組件,utility 方法和其他一些組件組成模式。

  mixins的缺點是Composition API背后的主要推動因素之一,讓我們快速了解一下它是如何工作的,然后再看它如何克服mixin問題。

二、Composition API 代碼提取及代碼重用

(一)代碼提取 —— Composition API的第一個明顯優點是提取邏輯很容易。

  讓我們使用Composition API重構上面定義的組件,以使我們定義的功能位於JavaScript模塊 useCounter 中(在特性描述前面加上“use”是一種Composition API命名約定)。

//useCounter.js
import { ref, computed } from "vue"; export default function () { const count = ref(0); const double = computed(() => count * 2) function increment() { count.value++; } return { count, double, increment } }

(二)代碼重用

  要在組件中使用該函數,我們只需將模塊導入組件文件並調用它(注意導入是一個函數)。這將返回我們定義的變量,隨后我們可以從 setup 函數中返回它們。

// MyComponent.js
import useCounter from "./useCounter.js"; export default { setup() { const { count, double, increment } = useCounter(); return { count, double, increment } } }

  乍一看,這似乎有點冗長而毫無意義,但讓我們來看看這種模式如何克服了前面討論的mixins問題。

三、Composition API 解決 mixin 的缺陷

1、命名沖突 - 解決了

  我們之前已經了解了mixin如何使用與消費者組件中的名稱相同的屬性,或者甚至更隱蔽地使用了消費者組件使用的其他mixin中的屬性。

  這不是Composition API的問題,因為我們需要顯式命名任何狀態或從合成函數返回的方法。

export default { setup () { const { someVar1, someMethod1 } = useCompFunction1(); const { someVar2, someMethod2 } = useCompFunction2(); return { someVar1, someMethod1, someVar2, someMethod2 } } }

  當命名沖突時就會很清楚的知曉。

2、隱式依賴 - 解決了!

  前面還看到mixin如何使用在消費組件上定義的 data 屬性,這可能會使代碼變得脆弱,並且很難進行推理。

  合成函數(Composition Function)還可以調用消費組件中定義的局部變量。不過,不同之處在於,現在必須將此變量顯式傳遞給合成函數

import useCompFunction from "./useCompFunction"; export default { setup () { // 某個局部值的合成函數需要用到
    const myLocalVal = ref(0); // 它必須作為參數顯式地傳遞
    const { ... } = useCompFunction(myLocalVal); } }

  總結:

1、mixin 模式表面上看起來很安全。然而,通過合並對象來共享代碼,由於它給代碼增加了脆弱性,並且掩蓋了推理功能的能力,因此成為一種反模式。

2、Composition API最聰明的部分是,它允許Vue依靠原生JavaScript中內置的保障措施來共享代碼,比如將變量傳遞給函數和模塊系統

3、這是否意味着Composition API在各方面都比Vue的經典API優越?不是的。在大多數情況下,你堅持使用經典API是沒有問題的。但是,如果你打算重用代碼,Composition API無疑是優越的。

以上來自英文:https://css-tricks.com/how-the-vue-composition-api-replaces-vue-mixins/ 的學習

網上很多譯文:https://blog.csdn.net/z591102/article/details/106682344/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM