掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
Vue3 已經(jīng)發(fā)布一段時間了,這個版本從底層實現(xiàn)到上層 API 設(shè)計都發(fā)生了非常大的變化,但具體改變了些什么呢?一起簡單盤點下:

目前創(chuàng)新互聯(lián)已為上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、網(wǎng)站托管維護(hù)、企業(yè)網(wǎng)站設(shè)計、華池網(wǎng)站維護(hù)等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
使用傳統(tǒng)的option配置方法寫組件的時候問題,隨著業(yè)務(wù)復(fù)雜度越來越高,代碼量會不斷的加大;由于相關(guān)業(yè)務(wù)的代碼需要遵循option的配置寫到特定的區(qū)域,導(dǎo)致后續(xù)維護(hù)非常的復(fù)雜,同時代碼可復(fù)用性不高,而composition-api就是為了解決這個問題而生。
使用傳統(tǒng)OptionsAPI時,新增或者修改一個需求,就需要分別在data,methods,computed里修改 。當(dāng)業(yè)務(wù)邏輯和功能越來越多的時候理解和維護(hù)復(fù)雜組件變得困難。
而Vue3 的組合式 API 將每個功能點抽成一個function使我們可以更加優(yōu)雅的組織我們的代碼。讓相關(guān)功能的代碼更加有序的組織在一起。
在 vue2.x 中,數(shù)據(jù)都是定義在data中。但是 Vue3.x 可以使用reactive和ref來進(jìn)行數(shù)據(jù)定義。那么ref和reactive他們有什么區(qū)別呢?
從原理角度對比:
ref用來創(chuàng)建一個包含響應(yīng)式的數(shù)據(jù)的引用對象。
源碼地址:https://github.com/vuejs/vue-next/blob/master/packages/reactivity/src/ref.ts。
從使用角度對比:
//watchEffect所指定的回調(diào)中用到的數(shù)據(jù)只要發(fā)生變化,則直接重新執(zhí)行回調(diào)。
watchEffect(()=>{
const x1 = sum.value
const x2 = person.age
console.log('watchEffect執(zhí)行了回調(diào)')
})
優(yōu)化前Virtual Dom的diff算法,需要遍歷所有節(jié)點,而且每一個節(jié)點都要比較舊的props和新的props有沒有變化。在Vue3.0中,只有帶PatchFlag的節(jié)點會被真正的追蹤,在后續(xù)更新的過程中,Vue不會追蹤靜態(tài)節(jié)點,只追蹤帶有PatchFlag的節(jié)點來達(dá)到加快渲染的效果。
vue
{{msg}}
export function render(_ctx,_cache,$props, $setup,$data,$options){
return (_openBlock(),_createBlock( span ,null,[
_createVNode( span ,null, vue ),
_createVNode( span ,null,_toDisplayString(_ctx.msg), 1 /* TEXT */),
_createVNode( span ,{
id: _ctx,hello
class: bar
},_toDisplayString(_ctx.msg),9 /* TEXT, PROPS */, [ id ])
}上面的源碼中1 /* TEXT */這個標(biāo)記就是 PatchFlag,Vue只會追蹤第二個和第三個帶有PatchFlag的節(jié)點。
在第三個span標(biāo)簽中PatchFlag變成了 9 /* TEXT, PROPS */, [ id ],提示我們這個dom元素中不僅有TEXT的變化,PROPS也可能會變化,后邊數(shù)組中的內(nèi)容則是有可能發(fā)生變化的屬性。而靜態(tài)添加的class沒有被標(biāo)記是因為 dom 元素的靜態(tài)屬性在渲染的時候就已經(jīng)創(chuàng)建了,并且是不會變動的。在后面進(jìn)行更新的時候,diff 算法是不會去管它的。
vue官方文檔:https://cn.vuejs.org/v2/guide/reactivity.html。
實現(xiàn)原理:
Object.defineProperty(data, 'count', {
get () {},
set () {}
})
存在問題:
實現(xiàn)原理:
MDN文檔中對Proxy與Reflect描述:
new Proxy(data, {
// 攔截讀取屬性值
get (target, prop) {
return Reflect.get(target, prop)
},
// 攔截設(shè)置屬性值或添加新屬性
set (target, prop, value) {
return Reflect.set(target, prop, value)
},
// 攔截刪除屬性
deleteProperty (target, prop) {
return Reflect.deleteProperty(target, prop)
}
})
proxy.name = 'tom'
Vue2: 組件必須有一個根標(biāo)簽。
Vue3: 組件可以沒有根標(biāo)簽, 可以直接寫多個根節(jié)點,內(nèi)部會將多個標(biāo)簽包含在一個Fragment虛擬元素中。
好處: 減少標(biāo)簽層級, 減小內(nèi)存占用,提升了渲染性能。
就像是一個「任意門」,將包裹組件html結(jié)構(gòu)傳送到任何指定的地方。
例如我們?nèi)粘i_發(fā)中經(jīng)常會使用到彈窗組件,Dialog組件會被渲染到一層層子組件內(nèi)部,處理樣式、定位都變得十分困難。這時我們希望將組件掛載在body上面,來更方便的控制Dialog的樣式。簡單來說,我們既希望繼續(xù)在組件內(nèi)部使用Dialog,又希望渲染的 DOM 結(jié)構(gòu)不嵌套在組件內(nèi)部的 DOM 中。就可以用到, 它可以在「不改變組件內(nèi)部元素父子關(guān)系」的情況下,建立一個傳送門將Dialog渲染的內(nèi)容傳送到body上面。
彈窗
我是App組件
加載中.....

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流