什么是Vue3的組合式 API?
組合式 API 是一系列 API 的集合,使我們可以使用函數(shù)而不是聲明選項(xiàng)的方式書(shū)寫(xiě) Vue 組件。它是一個(gè)概括性的術(shù)語(yǔ),涵蓋了以下方面的 API:
- 響應(yīng)性 API:例如
ref()
和reactive()
,使我們可以直接創(chuàng)建響應(yīng)式狀態(tài)、計(jì)算屬性和偵聽(tīng)器。 - 生命周期鉤子:例如
onMounted()
和onUnmounted()
,使我們可以在組件各個(gè)生命周期階段添加邏輯。 - 依賴(lài)注入:例如
provide()
和inject()
,使我們可以在使用響應(yīng)性 API 時(shí),利用 Vue 的依賴(lài)注入系統(tǒng)。
在 Vue 3 中,組合式 API 基本上都會(huì)配合<script setup>
語(yǔ)法在單文件組件中使用。


組合式api所做的
組合式api所實(shí)現(xiàn)就是將業(yè)務(wù)流程集中化,而不是碎片化,業(yè)務(wù)流程隨著時(shí)間滾動(dòng)。形成一個(gè)時(shí)間流式的業(yè)務(wù)流。
為什么要有組合式 API?
更好的邏輯復(fù)用
組合式 API 最基本的優(yōu)勢(shì)是它使我們能夠通過(guò)組合函數(shù)來(lái)實(shí)現(xiàn)更加簡(jiǎn)潔高效的邏輯復(fù)用。在選項(xiàng)式 API 中我們主要的邏輯復(fù)用機(jī)制是 mixins,而組合式 API 解決了?mixins 的所有缺陷。
組合式 API 提供的邏輯復(fù)用能力孵化了一些非常棒的社區(qū)項(xiàng)目,比如?VueUse,一個(gè)不斷成長(zhǎng)的工具型組合式函數(shù)集合。組合式 API 還為其他第三方狀態(tài)管理庫(kù)與 Vue 的響應(yīng)式系統(tǒng)之間的集成提供了一套簡(jiǎn)潔清晰的機(jī)制,例如?RxJS。
更靈活的代碼組織
許多用戶(hù)喜歡選項(xiàng)式 API 的原因是因?yàn)樗谀J(rèn)情況下就能夠讓人寫(xiě)出有組織的代碼:大部分代碼都自然地被放進(jìn)了對(duì)應(yīng)的選項(xiàng)里。然而,選項(xiàng)式 API 在單個(gè)組件的邏輯復(fù)雜到一定程度時(shí),會(huì)面臨一些無(wú)法忽視的限制。這些限制主要體現(xiàn)在需要處理多個(gè)邏輯關(guān)注點(diǎn)的組件中,這是我們?cè)谠S多 Vue 2 的實(shí)際案例中所觀察到的。
我們以 Vue CLI GUI 中的文件瀏覽器組件為例:這個(gè)組件承擔(dān)了以下幾個(gè)邏輯關(guān)注點(diǎn):
- 追蹤當(dāng)前文件夾的狀態(tài),展示其內(nèi)容
- 處理文件夾的相關(guān)操作 (打開(kāi)、關(guān)閉和刷新)
- 支持創(chuàng)建新文件夾
- 可以切換到只展示收藏的文件夾
- 可以開(kāi)啟對(duì)隱藏文件夾的展示
- 處理當(dāng)前工作目錄中的變更
你可以看到,處理相同邏輯關(guān)注點(diǎn)的代碼被強(qiáng)制拆分在了不同的選項(xiàng)中,位于文件的不同部分。在一個(gè)幾百行的大組件中,要讀懂代碼中的一個(gè)邏輯關(guān)注點(diǎn),需要在文件中反復(fù)上下滾動(dòng),這并不理想。
另外,如果我們想要將一個(gè)邏輯關(guān)注點(diǎn)抽取重構(gòu)到一個(gè)可復(fù)用的工具函數(shù)中,需要從文件的多個(gè)不同部分找到所需的正確片段。
而如果用組合式 API 重構(gòu)這個(gè)組件,將會(huì)變成下面右邊這樣:

響應(yīng)式(核心類(lèi))
1. ref()–定義響應(yīng)式數(shù)據(jù)
ref()
接受一個(gè)基本數(shù)據(jù)類(lèi)型的參數(shù),返回一個(gè)響應(yīng)式的、可更改的 ref
對(duì)象,此對(duì)象只有一個(gè)指向其內(nèi)部值的屬性?.value
。如果將一個(gè)對(duì)象賦值給 ref
,那么這個(gè)對(duì)象將通過(guò)?reactive()
?轉(zhuǎn)為具有深層次響應(yīng)式的對(duì)象。
2. reactive()–定義響應(yīng)式數(shù)據(jù)
reactive()
接受一個(gè)對(duì)象,包括json數(shù)據(jù)和數(shù)組都可以,返回一個(gè)對(duì)象的響應(yīng)式代理。
3. computed()–計(jì)算屬性
computed()
接受一個(gè) getter 函數(shù),返回一個(gè)只讀的響應(yīng)式?ref
對(duì)象。該 ref 通過(guò)?.value
?暴露 getter 函數(shù)的返回值。它也可以接受一個(gè)帶有?get
?和?set
?函數(shù)的對(duì)象來(lái)創(chuàng)建一個(gè)可寫(xiě)的 ref 對(duì)象。
4.watch()–監(jiān)聽(tīng)
watch()
監(jiān)聽(tīng)一個(gè)或多個(gè)響應(yīng)式數(shù)據(jù)源,并在數(shù)據(jù)源變化時(shí)調(diào)用所給的回調(diào)函數(shù)。默認(rèn)是懶監(jiān)聽(tīng),即源發(fā)生變化時(shí)才執(zhí)行回調(diào)函數(shù)。函數(shù)接受三個(gè)參數(shù):
- 監(jiān)聽(tīng)器的源數(shù)據(jù)(一個(gè)函數(shù),返回一個(gè)值。一個(gè)ref。一個(gè)響應(yīng)式對(duì)象。或以上三種類(lèi)型組成的數(shù)組)
- 第二個(gè)參數(shù)是在發(fā)生變化時(shí)要調(diào)用的回調(diào)函數(shù)。接受三個(gè)參數(shù):新值、舊值,以及一個(gè)用于注冊(cè)副作用清理的回調(diào)函數(shù)
- 第三個(gè)可選的參數(shù)是一個(gè)對(duì)象(對(duì)象屬性支持
immediate
,deep
,flush
,onTrack / onTrigger
)
5. watchEffect()
watchEffect()
立即運(yùn)行一個(gè)函數(shù),同時(shí)響應(yīng)式地追蹤其依賴(lài),并在依賴(lài)更改時(shí)重新執(zhí)行。
- 第一個(gè)參數(shù)就是要運(yùn)行的副作用函數(shù)
- 第二個(gè)參數(shù)就是一個(gè)可選的對(duì)象,跟watch第三個(gè)參數(shù)一致
watch() 跟 watchEffect()區(qū)別
- 1.
watch
是惰性執(zhí)行,也就是只有監(jiān)聽(tīng)的值發(fā)生變化的時(shí)候才會(huì)執(zhí)行,但是watchEffect
不同,每次代碼加載watchEffect都會(huì)執(zhí)行。 - 2.
watch
?會(huì)明確監(jiān)聽(tīng)某一個(gè)數(shù)據(jù),而?watchEffect
?則是監(jiān)聽(tīng)回調(diào)函數(shù)中響應(yīng)數(shù)據(jù)。 - 3.
watch
可以訪問(wèn)之前的值,而watchEffect
不可以。
注意
1、setup是vue3中的一個(gè)全新的配置項(xiàng),值為一個(gè)函數(shù);
2、setup是所有CompositionAPI(組合API)的基礎(chǔ),組件中所用到的數(shù)據(jù)、方法等都需要在setup中進(jìn)行配置;
setup中的兩種返回值
返回一個(gè)對(duì)象,對(duì)象中的屬性、方法,在模板中均可直接使用(重點(diǎn))
export default {
name: 'App',
setup(){
// 數(shù)據(jù)
let name = '張三'
let age = '18'
// 方法
function sayHello(){
alert(`我叫${name},我${age}歲了,你好啊`)
}
// 第一種return,返回一個(gè)對(duì)象
return{
name,
age,
sayHello
}
}
}
返回一個(gè)渲染函數(shù):可以自定義渲染內(nèi)容(了解)
export default {
name: 'App',
setup(){
// 數(shù)據(jù)
let name = '張三'
let age = '18'
// 方法
function sayHello(){
alert(`我叫${name},我${age}歲了,你好啊`)
}
// 第二種return,返回一個(gè)渲染函數(shù)
return ()=> { return h('h1','尚硅谷') }
// 簡(jiǎn)寫(xiě)
// return ()=> h('h1','尚硅谷')
}
}
setup不能是一個(gè)async函數(shù),因?yàn)榉祷刂挡辉偈莚eturn的對(duì)象,而是promise,模板看不到return對(duì)象中的屬性;