vue项目统一响应_Vue响应式原理及总结
Vue 的響應(yīng)式原理是核心是通過 ES5 的保護對象的 Object.defindeProperty 中的訪問器屬性中的 get 和 set 方法,data 中聲明的屬性都被添加了訪問器屬性,當讀取 data 中的數(shù)據(jù)時自動調(diào)用 get 方法,當修改 data 中的數(shù)據(jù)時,自動調(diào)用 set 方法,檢測到數(shù)據(jù)的變化,會通知觀察者 Wacher,觀察者 Wacher自動觸發(fā)重新render 當前組件(子組件不會重新渲染),生成新的虛擬?DOM 樹,Vue 框架會遍歷并對比新虛擬?DOM 樹和舊虛擬?DOM 樹中每個節(jié)點的差別,并記錄下來,最后,加載操作,將所有記錄的不同點,局部修改到真實 DOM 樹上。
虛擬DOM (Virtaul DOM): 用 js 對象模擬的,保存當前視圖內(nèi)所有 DOM 節(jié)點對象基本描述屬性和節(jié)點間關(guān)系的樹結(jié)構(gòu)。用 js 對象,描述每個節(jié)點,及其父子關(guān)系,形成虛擬 DOM 對象樹結(jié)構(gòu)。
項目中常遇到的關(guān)于vue響應(yīng)式的記錄與總結(jié):
因為只要在 data 中聲明的基本數(shù)據(jù)類型的數(shù)據(jù),基本不存在數(shù)據(jù)不響應(yīng)問題,所以重點介紹數(shù)組和對象在vue中的數(shù)據(jù)響應(yīng)問題,vue可以檢測對象屬性的修改,但無法監(jiān)聽數(shù)組的所有變動及對象的新增和刪除,只能使用數(shù)組變異方法及$set方法。
可以看到,arrayMethods?首先繼承了?Array,然后對數(shù)組中所有能改變數(shù)組自身的方法,如?push、pop?等這些方法進行重寫。重寫后的方法會先執(zhí)行它們本身原有的邏輯,并對能增加數(shù)組長度的 3 個方法?push、unshift、splice?方法做了判斷,獲取到插入的值,然后把新添加的值變成一個響應(yīng)式對象,并且再調(diào)用?ob.dep.notify()?手動觸發(fā)依賴通知,這就很好地解釋了用?vm.items.splice(newLength)?方法可以檢測到變化。。
1.?向響應(yīng)式的數(shù)組或者對象中修改已有的屬性的方法
當想要修改對象或者屬性,并非新增屬性時,一個已經(jīng)在 data 中聲明過的響應(yīng)式數(shù)據(jù),可以直接操作改變,數(shù)據(jù)改變會經(jīng)過上圖的步驟,觸發(fā)視圖改變。直接obj.xxx = xxx 即可,數(shù)組除外,但是后臺傳過來的 json 數(shù)組,數(shù)組中嵌套的對象也可以直接修改數(shù)組中的對象,因為 Object.defindeProperty 的缺陷導(dǎo)致無法監(jiān)聽數(shù)組的變動,但始終會深度遍歷data中數(shù)據(jù),給數(shù)組中嵌套的對象添加上 get 和 set 方法,完成對對象的監(jiān)聽。所以數(shù)組中嵌套的對象的情況是可以直接修改數(shù)組中的對象,并且保持響應(yīng)式。
2.?向響應(yīng)式的數(shù)組或者對象中新增一個響應(yīng)式的屬性的方法this.$set()或者數(shù)組變異方法
即使是一個后臺傳過來的 json 數(shù)組,也可以使用this.$set向數(shù)組中的其中一個對象中添加一個響應(yīng)式的屬性,例如 this.$set(arr[0], 'xxx', xxx) 。或者使用數(shù)組變異方法例如splice,更多數(shù)組變異方法可以參考vue文檔。
3.?data中聲明過的數(shù)組或者對象,整體替換數(shù)組或者對象保持響應(yīng)式
向響應(yīng)式的數(shù)組和對象替換為新的響應(yīng)式數(shù)據(jù),可直接復(fù)制,因為data中聲明的數(shù)據(jù)已經(jīng)添加了訪問器屬性setter,當重新賦值一個新的堆內(nèi)存地址時,該數(shù)組或者對象也會被循環(huán)遍歷添加訪問器屬性,所以也是有響應(yīng)式的。
4.??vue無法監(jiān)聽對象的新增和刪除,直接通過obj.xxx = xxx新增一個沒有的屬性,同時修改當前組件的一個響應(yīng)式的數(shù)據(jù),會重新觸發(fā)當前組件重新render,可以讓非響應(yīng)式數(shù)據(jù)也保持更新狀態(tài)(并非響應(yīng)式) 。
給一個數(shù)據(jù)添加一個非響應(yīng)式的數(shù)據(jù),例如一個已經(jīng)在data中聲明過的數(shù)據(jù)obj,obj.xxx=xxx,新增一個原本沒有的數(shù)據(jù),同時修改組件中一個其他的響應(yīng)式數(shù)據(jù),該obj也會同步更新到最新的數(shù)據(jù),另一種情況,當你向一個對象或者數(shù)組中同時增加一個響應(yīng)式和非響應(yīng)式數(shù)據(jù),非響應(yīng)式數(shù)據(jù)也會同步更新到頁面。
總結(jié):只要觸發(fā)當前組件重新render,就可以讓數(shù)據(jù)保持更新的狀態(tài),例如this.$forceUpdate()。
為什么vue不能監(jiān)聽數(shù)組的變化?
Object.defindProperty雖然能夠?qū)崿F(xiàn)雙向綁定了,但是還是有缺點,只能對對象的屬性進行數(shù)據(jù)劫持,所以會深度遍歷整個對象,不管層級有多深,只要數(shù)組中嵌套有對象,就能監(jiān)聽到對象的數(shù)據(jù)變化無法監(jiān)聽到數(shù)組的變化,Proxy就沒有這個問題,可以監(jiān)聽整個對象的數(shù)據(jù)變化,所以用vue3.0會用Proxy代替definedProperty。
最后實現(xiàn)一個數(shù)據(jù)雙向綁定原理
更深的底層原理還在學習中,完全消化以后會繼續(xù)分享,嗯,就醬~
總結(jié)
以上是生活随笔為你收集整理的vue项目统一响应_Vue响应式原理及总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言数学语文英语成绩编程,急求一编程题
- 下一篇: python mysql dbutils