正如你所期望的那樣,Vue 3帶來了很多令人興奮的新功能。值得慶幸的是,Vue團隊主要是在當前API的基礎上引入了一些補充和改進,而不是進行重大更改,所以已經瞭解Vue 2的人應該很快就會對新的語法感到適應。
讓我們從你們大多數人可能聽說過的API開始吧......
Composition API
Composition API是Vue的下一個主要版本中最常用的討論和特色語法。這是一種全新的邏輯重用和程式碼組織方法·
當前,我們使用所謂的Options API構建元件。為了向Vue元件新增邏輯,我們填充(選項)屬性,例如資料,方法,計算的等。這種方法的最大缺點是,這本身並不是有效的JavaScript程式碼。您需要確切瞭解模板中可以訪問哪些屬性,以及此關鍵字的行為。在後臺,Vue編譯器需要將此屬性轉換為工作程式碼。因此,我們無法從自動建議或型別檢查中受益。
Composition API的目的是通過將當前可用元件屬性作為JavaScript函式暴露出來的機制來解決這個問題。Vue核心團隊將Composition API描述為“一組基於功能的附加API,可以靈活地組合元件邏輯”。使用 Composition API 編寫的程式碼更易讀,而且沒有任何幕後的魔力,更容易閱讀和學習。
讓我們來看看一個非常簡單的例子,看看使用新的Composition API的元件是如何工作的。
<template> <button @click="increment"> Count is: {{ state.count }}, double is: {{ state.double }} </button> </template> <script> import { reactive, computed } from 'vue' export default { setup() { const state = reactive({ count: 0, double: computed(() => state.count * 2) }) function increment() { state.count++ } return { state, increment } } } </script>
現在,讓我們把這段程式碼分解成幾段,以瞭解發生了什麼事
import { ref, computed, onMounted } from 'vue'
正如我之前提到的Component API是以函式的形式展示元件屬性,所以第一步就是匯入我們需要的函式。在我們的例子中,我們需要用 ref
建立reactive reference,用 computed
建立computed屬性,用onMounted
訪問mounted的掛載生命週期鉤子。·
現在你可能會想知道這個神祕的 setup
方法是什麼?
export default { setup() {} }
簡而言之,它只是一個函式,向模板返回屬性和函式。就是這樣。我們在這裡宣告所有的反應式屬性、計算屬性、watchers和生命週期鉤子,然後返回它們,這樣它們就可以在模板中使用。·
我們沒有從setup函式中返回的東西將不能在模板中使用
const count = ref(0)
根據上面的內容,我們用ref函式宣告瞭一個叫count的反應式屬性。它可以包裹任何基元或物件,並返回它的反應式引用。傳入的元素的值將被儲存在建立的引用的value屬性中。例如,如果你想訪問count引用的值,你需要顯式請求count.value。
const double = computed(() => count.value * 2) function increment() { count.value++ }
而這正是我們在宣告計算屬性雙倍和增量函式時所做的
onMounted(() => console.log('component mounted!'))
當元件被掛載時,我們用onMounted鉤子記錄一些訊息,只是為了讓你知道你可以 simle
return { count, double, increment }
最後我們用 increment
方法返回 count
和 double
屬性,使其在模板中可用
<template> <button @click="increment"> Count is: {{ count }}, double is {{ double }}. Click to increment. </button> </template>
現在我們可以像以前的Options API一樣,在模板中訪問由setup方法返回的屬性和函式
這是一個簡單的例子,用Options API也可以很容易實現。新的Composition API的真正好處不僅僅是以不同的方式編碼,當涉及到重用我們的程式碼/邏輯時,好處就會顯現出來
使用Composition API重用程式碼
新的Composition API有更多的優勢。考慮到程式碼的重用。目前,如果我們想在其他元件之間共享一些程式碼,有兩種選擇----mixins和scoped slots。這兩種方案都有其缺點。
假設我們想提取 counter
的功能,並在其他元件中重用。下面你可以看到它如何與可用的API和新的Component API一起使用
讓我們從mixins開始說起
import CounterMixin from './mixins/counter' export default { mixins: [CounterMixin] }
mixins最大的缺點是,我們對它究竟在我們的元件中加入了什麼東西一無所知。這使得它不僅難以推理,而且還可能導致與現有的屬性和函式的名稱碰撞。·
這時候就到了加scoped slots的時候了
<template>
<Counter v-slot="{ count, increment }">
{{ count }}
<button @click="increment">Increment</button>
</Counter>
</template>
有了scoped slots,我們就可以通過v-slot屬性準確地知道我們可以通過v-slot屬性訪問哪些屬性,這樣就更容易理解程式碼了。這種方法的缺點是,我們只能在模板中訪問,而且只能在Counter元件作用域中使用
現在是Composition API的時候了
function useCounter() { const count = ref(0) function increment () { count.value++ } return { count, incrememt } } export default { setup () { const { count, increment } = useCounter() return { count, increment } } }
更加優雅了,不是嗎?我們不受模板和元件範圍的限制,可以準確地知道我們可以從counter中訪問哪些屬性。此外,我們還可以從編輯器中的程式碼完成中受益,因為useCounter只是一個返回一些屬性的函式。在幕後沒有什麼魔法,所以編輯器可以幫助我們進行型別檢查和建議。
這也是一種比較優雅的使用第三方庫的方式。例如,如果我們想使用Vuex,我們可以顯式使用Store函式,而不是汙染Vue原型(this.$store)。這種方法也消除了Vue外掛的幕後魔法
const { commit, dispatch } = useStore()
如果你想了解更多關於Composition API和它的用例,我強烈推薦你閱讀Vue團隊的這篇文件,它解釋了新的API背後的原因,並推薦了它的最佳用例。還有一個很好的資源庫,裡面有Vue核心團隊的Thorsten Lünborg提供的Composition API使用案例