1.拉開(kāi)序幕的setup
理解:Vue3.0中一個(gè)新的配置項(xiàng),值為一個(gè)函數(shù)丸相。
setup是所有Composition API(組合API)“ 表演的舞臺(tái) ”。
組件中所用到的:數(shù)據(jù)彼棍、方法等等灭忠,均要配置在setup中。
setup函數(shù)的兩種返回值:
若返回一個(gè)對(duì)象座硕,則對(duì)象中的屬性弛作、方法, 在模板中均可以直接使用。(重點(diǎn)關(guān)注;摇)
若返回一個(gè)渲染函數(shù):則可以自定義渲染內(nèi)容缆蝉。(了解)
注意點(diǎn):
盡量不要與Vue2.x配置混用
Vue2.x配置(data、methos瘦真、computed...)中可以訪問(wèn)到setup中的屬性、方法黍瞧。
但在setup中不能訪問(wèn)到Vue2.x配置(data诸尽、methos、computed...)印颤。
如果有重名, setup優(yōu)先您机。
setup不能是一個(gè)async函數(shù),因?yàn)榉祷刂挡辉偈莚eturn的對(duì)象, 而是promise, 模板看不到return對(duì)象中的屬性年局。(后期也可以返回一個(gè)Promise實(shí)例际看,但需要Suspense和異步組件的配合)
2.ref函數(shù)
作用: 定義一個(gè)響應(yīng)式的數(shù)據(jù)
語(yǔ)法: const xxx = ref(initValue)
創(chuàng)建一個(gè)包含響應(yīng)式數(shù)據(jù)的引用對(duì)象(reference對(duì)象,簡(jiǎn)稱ref對(duì)象)矢否。
JS中操作數(shù)據(jù): xxx.value
模板中讀取數(shù)據(jù): 不需要.value仲闽,直接:<div>{{xxx}}</div>
備注:
接收的數(shù)據(jù)可以是:基本類型、也可以是對(duì)象類型僵朗。
基本類型的數(shù)據(jù):響應(yīng)式依然是靠Object.defineProperty()的get與set完成的赖欣。
對(duì)象類型的數(shù)據(jù):內(nèi)部 “ 求助 ” 了Vue3.0中的一個(gè)新函數(shù)—— reactive函數(shù)。
3.reactive函數(shù)
作用: 定義一個(gè)對(duì)象類型的響應(yīng)式數(shù)據(jù)(基本類型不要用它验庙,要用ref函數(shù))
語(yǔ)法:const 代理對(duì)象= reactive(源對(duì)象)接收一個(gè)對(duì)象(或數(shù)組)顶吮,返回一個(gè)代理對(duì)象(Proxy的實(shí)例對(duì)象,簡(jiǎn)稱proxy對(duì)象)
reactive定義的響應(yīng)式數(shù)據(jù)是“深層次的”粪薛。
內(nèi)部基于 ES6 的 Proxy 實(shí)現(xiàn)悴了,通過(guò)代理對(duì)象操作源對(duì)象內(nèi)部數(shù)據(jù)進(jìn)行操作。
4.Vue3.0中的響應(yīng)式原理
vue2.x的響應(yīng)式
實(shí)現(xiàn)原理:
對(duì)象類型:通過(guò)Object.defineProperty()對(duì)屬性的讀取、修改進(jìn)行攔截(數(shù)據(jù)劫持)湃交。
數(shù)組類型:通過(guò)重寫(xiě)更新數(shù)組的一系列方法來(lái)實(shí)現(xiàn)攔截熟空。(對(duì)數(shù)組的變更方法進(jìn)行了包裹)。
Object.defineProperty(data,'count', {
get() {},
set() {}
})
存在問(wèn)題:
新增屬性巡揍、刪除屬性, 界面不會(huì)更新痛阻。
直接通過(guò)下標(biāo)修改數(shù)組, 界面不會(huì)自動(dòng)更新。
Vue3.0的響應(yīng)式
實(shí)現(xiàn)原理:
通過(guò)Proxy(代理):? 攔截對(duì)象中任意屬性的變化, 包括:屬性值的讀寫(xiě)腮敌、屬性的添加阱当、屬性的刪除等。
通過(guò)Reflect(反射):? 對(duì)源對(duì)象的屬性進(jìn)行操作糜工。
MDN文檔中描述的Proxy與Reflect:
Proxy:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Reflect:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
newProxy(data, {
? ? // 攔截讀取屬性值
get(target,prop) {
? ? returnReflect.get(target,prop)
?? },
// 攔截設(shè)置屬性值或添加新屬性
set(target,prop,value) {
? ? returnReflect.set(target,prop,value)
?? },
// 攔截刪除屬性
deleteProperty(target,prop) {
? ? returnReflect.deleteProperty(target,prop)
?? }
})
proxy.name='tom'
5.reactive對(duì)比ref
從定義數(shù)據(jù)角度對(duì)比:
ref用來(lái)定義:基本類型數(shù)據(jù)弊添。
reactive用來(lái)定義:對(duì)象(或數(shù)組)類型數(shù)據(jù)。
備注:ref也可以用來(lái)定義對(duì)象(或數(shù)組)類型數(shù)據(jù), 它內(nèi)部會(huì)自動(dòng)通過(guò)reactive轉(zhuǎn)為代理對(duì)象捌木。
從原理角度對(duì)比:
ref通過(guò)Object.defineProperty()的get與set來(lái)實(shí)現(xiàn)響應(yīng)式(數(shù)據(jù)劫持)油坝。
reactive通過(guò)使用Proxy來(lái)實(shí)現(xiàn)響應(yīng)式(數(shù)據(jù)劫持), 并通過(guò)Reflect操作源對(duì)象內(nèi)部的數(shù)據(jù)。
從使用角度對(duì)比:
ref定義的數(shù)據(jù):操作數(shù)據(jù)需要.value刨裆,讀取數(shù)據(jù)時(shí)模板中直接讀取不需要.value澈圈。
reactive定義的數(shù)據(jù):操作數(shù)據(jù)與讀取數(shù)據(jù):均不需要.value。
6.setup的兩個(gè)注意點(diǎn)
setup執(zhí)行的時(shí)機(jī)
在beforeCreate之前執(zhí)行一次帆啃,this是undefined瞬女。
setup的參數(shù)
props:值為對(duì)象,包含:組件外部傳遞過(guò)來(lái)努潘,且組件內(nèi)部聲明接收了的屬性诽偷。
context:上下文對(duì)象
attrs: 值為對(duì)象,包含:組件外部傳遞過(guò)來(lái)疯坤,但沒(méi)有在props配置中聲明的屬性, 相當(dāng)于 this.$attrs报慕。
slots: 收到的插槽內(nèi)容, 相當(dāng)于 this.$slots。
emit: 分發(fā)自定義事件的函數(shù), 相當(dāng)于 this.$emit压怠。