Vue 3.0 中令人激動的新功能:Composition API

菜鳥的飛翔夢發表於2020-09-08

正如你所期望的那樣,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使用案例

以上示例來自:https://composition-api.vuejs.org/#basic-example

相關文章