一、為了解決多業務線交叉、難以維護的復雜場景,Vue3認為以業務分割邏輯代碼更合理。
例如:當前組件有一個顯示某個用戶的倉庫列表的視圖。此外,我們還希望有搜索和篩選功能。在Vue2.x中代碼大致如下。
// src/components/UserRepositories.vue export default { components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList }, props: { user: { type: String, required: true } }, data () { return { repositories: [], // 1 filters: { ... }, // 3 searchQuery: '' // 2 } }, computed: { filteredRepositories () { ... }, // 3 repositoriesMatchingSearchQuery () { ... }, // 2 }, watch: { user: 'getUserRepositories' // 1 }, methods: { getUserRepositories () { // 使用 `this.user` 獲取用戶倉庫 }, // 1 updateFilters () { ... }, // 3 }, mounted () { this.getUserRepositories() // 1 } }
如果不熟悉該段代碼的人第一次閱讀,需要不停在 data、methods、computed 以及各個生命周期中來回查找相關業務代碼,如果業務更復雜,代碼的碎片化會更嚴重,導致難以維護。
如果能夠將同一個邏輯關注點相關代碼收集在一起會更好。而這正是組合式 API 使我們能夠做到的。
二、組合式API的基礎用法
先來寫一段簡單的組合式API代碼:
<script lang="ts"> import { defineComponent, ref, reactive, toRefs } from 'vue' export default defineComponent({ setup() { let name = ref('') let age = ref(0) let obj = reactive({ name: name.value, age: age.value }) return toRefs(obj) }, }) </script>
(1) setup
1.1 setup(props, context)
新的 setup
選項在組件創建之前執行,一旦 props
被解析,就將作為組合式 API 的入口。
在 setup
中你應該避免使用 this
,因為它不會找到組件實例。
setup
的調用發生在 data
property、computed
property 或 methods
被解析之前,所以它們無法在 setup
中被獲取。
1.2 參數介紹:
第一個參數 props :
setup
函數中的第一個參數是 props
。props 是響應式的。但不可以解構,否則會失去響應性。
如果需要解構 props,建議使用 refs (后文介紹)
第二個參數 context :
const { attrs, slots, emit } = context // Attributes,插槽,觸發事件
非響應式,可直接解構: setup(props, { attrs, slots, emit })
請注意,與 props
不同,attrs
和 slots
是非響應式的。如果你打算根據 attrs
或 slots
更改應用副作用,那么應該在 onUpdated
生命周期鈎子中執行此操作。
另外在 Vue3 中,beforeCreate 和 created 鈎子函數將不再適用,其他鈎子有略微改動,參考下圖
(2) ref 、reactive 、torefs
2.1 ref
ref
接收參數並將其包裹在一個帶有 value
property 的對象中返回,然后可以使用該 property 訪問或更改響應式變量的值
let name = ref('')
let age = ref(0) return { name,
age }
2.2 reactive
如果將對象分配為 ref 值,則通過 reactive 方法使該對象具有高度的響應式。
setup() { let name = ref('') let age = ref(0) let obj = reactive({ name: name.value, age: age.value }) return toRefs(obj) }
2.3 toRefs
將響應式對象轉換為普通對象,其中結果對象的每個 property 都是指向原始對象相應 property 的 ref
。
const state = reactive({ foo: 1, bar: 2 }) const stateAsRefs = toRefs(state) // ref 和原始 property 已經“鏈接”起來了 state.foo++ console.log(stateAsRefs.foo.value) // 2 stateAsRefs.foo.value++ console.log(state.foo) // 3
以上內容參考自 介紹 | Vue.js (vuejs.org)