vue 实例化几种方式_Vue双向数据绑定
一、vue實(shí)現(xiàn)數(shù)據(jù)雙向綁定的主要是:
采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個(gè)屬性的setter、getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者,觸發(fā)相應(yīng)監(jiān)聽回調(diào)。
當(dāng)創(chuàng)建Vue實(shí)例時(shí),vue會(huì)遍歷data選項(xiàng)的屬性,利用Objet.defineProperty為屬性添加getter和setter對數(shù)據(jù)的讀取進(jìn)行劫持(getter用來依賴收集,setter用來派發(fā)更新),并且在內(nèi)部追蹤依賴,在屬性被訪問和修改時(shí)通知變化。
每個(gè)組件實(shí)例會(huì)有對應(yīng)的watcher實(shí)例,在組件渲染的過程中記錄依賴的所有數(shù)據(jù)屬性(進(jìn)行依賴收集,還有computed watcher,user watcher實(shí)例),之后依賴項(xiàng)被該改動(dòng)時(shí),setter方法會(huì)通知依賴與此data的watcher實(shí)例重新計(jì)算(派發(fā)更新),從而使它關(guān)聯(lián)的組件重新渲染。
二、單向數(shù)據(jù)綁定流和雙向數(shù)據(jù)綁定
1. 單向數(shù)據(jù)綁定:數(shù)據(jù)流是單向的。
優(yōu)點(diǎn):數(shù)據(jù)流動(dòng)方向可以追蹤,流動(dòng)單一,追查問題的時(shí)候可以更快捷。
缺點(diǎn):寫起來不太方便。要使UI發(fā)生變更就必須創(chuàng)建各種action來維護(hù)對應(yīng)的state
2.雙向數(shù)據(jù)綁定:數(shù)據(jù)之間是相通的,將數(shù)據(jù)變更的操作隱藏在框架內(nèi)部。
優(yōu)點(diǎn):在表單交互較多的場景下,會(huì)簡化大量與業(yè)務(wù)無關(guān)的代碼。
缺點(diǎn):無法追蹤局部狀態(tài)的變化,增加了出錯(cuò)時(shí)debug的難度。
三、為什么在Vue3.0采用了Proxy,拋棄了Object.defineProperty
Object.defineProperty本身有一定的監(jiān)控到數(shù)組下標(biāo)變化的能力,但是在Vue中,從性能/體驗(yàn)的性價(jià)比考慮,棄用了這個(gè)特性(Vue為什么不能檢測數(shù)組的變動(dòng))。為了解決這個(gè)問題,經(jīng)過Vue內(nèi)部處理后可以使用以下幾種方法來監(jiān)聽數(shù)組
push()、pop()、shift()、unshift()、splice()、sort()、reverse()
由于只針對了以上7種方法進(jìn)行了hack處理,所以其他數(shù)組的屬性也是檢測不到的,還是具有一定的局限性。
Object.defineProperty只能劫持對象的屬性,因此需要對每個(gè)對象的每個(gè)屬性進(jìn)行遍歷。Vue 2.x是通過遞歸+遍歷data對象來實(shí)現(xiàn)對數(shù)據(jù)的監(jiān)聽的,如果屬性值也是對象那么需要深度遍歷,顯然如果能劫持一個(gè)完整的對象才是更好的選擇。Proxy可以劫持整個(gè)對象,并返回一個(gè)新的對象。Proxy不僅可以代理對象,代理數(shù)組。還可以代理動(dòng)態(tài)增加的屬性。
四、Proxy相較于Object.defineProperty的優(yōu)勢
1.直接監(jiān)聽對象而非屬性
2.直接監(jiān)聽數(shù)組的變化
3.攔截方式較多
4.Proxy返回一個(gè)新對象,可以只操作新對象達(dá)到目的,而Object.defineProperty只能遍歷對象屬性直接修改(需要用深拷貝進(jìn)行修改)
5.Proxy作為新標(biāo)準(zhǔn)將受到瀏覽器廠商重點(diǎn)持續(xù)的性能優(yōu)化
6.Proxy不能用polyfill來兼容,polyfill主要撫平不同瀏覽器之間對js實(shí)現(xiàn)的差異。
五、
1.核心實(shí)現(xiàn)類:
1)Observer:它的作用是給對象的屬性添加getter和setter,用于以來收集和派發(fā)更新
2)Dep:用于收集當(dāng)前響應(yīng)式對象的依賴關(guān)系,每個(gè)響應(yīng)式對象包括子對象都擁有一個(gè)Dep實(shí)例(里面subs是Watcher實(shí)例數(shù)組),當(dāng)數(shù)據(jù)有變更時(shí),會(huì)通過dep.notify()通知各個(gè)watcher。
3)Watcher:觀察者對象,實(shí)例分為渲染watcher(render watcher),計(jì)算屬性watcher(computed watcher),偵聽器watcher(user watcher)三種
2.Watcher和Dep的關(guān)系
watcher中實(shí)例化了dep并向dep.subs中添加了訂閱者,dep通過notify遍歷了dep.subs通知每個(gè)watcher更新。
3.依賴收集
1)initState時(shí),對computed屬性初始化時(shí),觸發(fā)computed watcher依賴收集
2)initState時(shí),對偵聽屬性初始化時(shí),觸發(fā)user watcher依賴收集
3)render()的過程,觸發(fā)render watcher依賴收集
4)re-render時(shí),vm.render()再次執(zhí)行,會(huì)移除所有subs中的watcher的訂閱,重新賦值。
4.派發(fā)更新
1)組建中對響應(yīng)的數(shù)據(jù)進(jìn)行了修改,觸發(fā)setter的邏輯
2)調(diào)用dep.notify()
3)遍歷所有的subs(Watcher實(shí)例),調(diào)用每一個(gè)watcher的update方法。
總結(jié)
以上是生活随笔為你收集整理的vue 实例化几种方式_Vue双向数据绑定的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: django 怎么加权限 静态资源目录_
- 下一篇: html特效指令,vue2——指令v-t