vue xunidom_vue的虚拟dom(Virtual DOM )
模板轉(zhuǎn)換成視圖的過程
在底層實現(xiàn)中Vue會將模板編譯成渲染函數(shù),當然我們也可以不寫模板,直接寫渲染函數(shù),以獲得更好的控制。
渲染函數(shù):渲染函數(shù)是用來生成Virtual DOM的;
VNode虛擬節(jié)點:vnode可以理解成dom節(jié)點的描述對象,它描述了應(yīng)該怎樣去創(chuàng)建真實的DOM節(jié)點;
patch(patching算法):虛擬DOM最核心的部分,它可以將vnode渲染成真實的DOM。這個過程是對比新舊虛擬節(jié)點之間有哪些不同,然后根據(jù)對比結(jié)果找出需要更新的的節(jié)點進行更新。其實際作用是在現(xiàn)有DOM上進行修改來實現(xiàn)更新視圖的目的;
Virtual DOM
Virtual DOM用JS對象來描述dom的節(jié)點(VNode),這個對象至少包含標簽名( tag)、屬性(attrs)和子元素對象( children)這三個屬性。它是對真實 DOM 的抽象,最終可以通過一系列操作把這個對象轉(zhuǎn)化為真實的dom。
具體步驟為
Virtual DOM 本質(zhì)上就是在 JS 和 DOM 之間做了一個緩存
Virtual DOM的作用
虛擬DOM的最終目標是將虛擬節(jié)點渲染到視圖上,但是如果直接使用虛擬節(jié)點覆蓋舊節(jié)點的話,會有很多不必要的DOM操作。例如,一個ul標簽下很多個li標簽,其中只有一個li有變化,這種情況下如果使用新的ul去替代舊的ul,因為這些不必要的DOM操作而造成了性能上的浪費。
為了避免不必要的DOM操作,虛擬DOM在虛擬節(jié)點映射到視圖的過程中,將虛擬節(jié)點與上一次渲染視圖所使用的舊虛擬節(jié)點(oldVnode)做對比,找出真正需要更新的節(jié)點來進行DOM操作,從而避免操作其他無需改動的DOM。
其實虛擬DOM在Vue.js主要做了兩件事:
提供與真實DOM節(jié)點所對應(yīng)的虛擬節(jié)點vnode;
將虛擬節(jié)點vnode和舊虛擬節(jié)點oldVnode進行對比,然后更新視圖;
Virtual DOM的diff算法
遞歸地進行同級vnode的diff,最終實現(xiàn)整個DOM樹的更新
步驟:
用 JavaScript 對象結(jié)構(gòu)表示 DOM 樹的結(jié)構(gòu);然后用這個樹構(gòu)建一個真正的 DOM 樹,插到文檔當中;
當狀態(tài)變更的時候,重新構(gòu)造一棵新的對象樹。然后用新的樹和舊的樹進行比較,記錄兩棵樹差異;
把所記錄的差異應(yīng)用到所構(gòu)建的真正的DOM樹上,視圖就更新了;
Virtual DOM的優(yōu)點
跨平臺的優(yōu)勢:由于 Virtual DOM 是以 JavaScript 對象為基礎(chǔ)而不依賴真實平臺環(huán)境,所以使它具有了跨平臺的能力,比如說瀏覽器平臺、Weex、Node 等;
提高效率:操作 DOM 慢,js運行效率高,所以將DOM對比操作放在JS層可以提高效率;
提高渲染性能:通過patch 的核心----diff 算法,找出本次DOM需要更新的節(jié)點來更新,其他的不更新。比如修改某個model 100次,從1加到100,那么有了Virtual DOM的緩存之后,只會把最后一次修改patch到view上。
nextTick
this.$nextTick(()=>{//操作。。。
})
1 Vue生命周期的created()鉤子函數(shù)進行的DOM操作一定要放在Vue.nextTick()的回調(diào)函數(shù)中;
2?當項目中你想在改變DOM元素的數(shù)據(jù)后基于新的dom做點什么,對新DOM一系列的js操作都需要放進Vue.nextTick()的回調(diào)函數(shù)中;
3?在使用某個第三方插件時 ,希望在vue生成的某些dom動態(tài)發(fā)生變化時重新應(yīng)用該插件,也會用到該方法;
改變數(shù)據(jù)有時不更新
1 vue實現(xiàn)數(shù)據(jù)雙向綁定有這么一個過程:當你把一個普通的 JavaScript 對象傳給 Vue 實例的 data 選項,Vue 將遍歷此對象所有的屬性,并使用Object.defineProperty() 把這些屬性全部轉(zhuǎn)為getter/setter。每個組件實例都有相應(yīng)的 watcher 實例對象,它會在組件渲染的過程中把屬性記錄為依賴,之后當依賴項的 setter 被調(diào)用時,會通知 watcher 重新計算,從而致使它關(guān)聯(lián)的組件得以更新。實現(xiàn)數(shù)據(jù)data變化更新視圖view。
var vm = newVue({
data:{
a:1; //vm.a 是響應(yīng)的
}
})
vm.b= 2; //vm.b 是非響應(yīng)的
2?沒有更新dom是因為改變數(shù)據(jù)之后Object.defineproperty()的set方法沒有被觸發(fā),即沒有監(jiān)測到數(shù)據(jù)更新。以下幾種情況會出現(xiàn)這個問題:
當你利用索引直接設(shè)置數(shù)組的一項時,例如:this.items[indexOfItem] = newValue;
當你修改數(shù)組的長度時,例如:this.items.length = newLength;
數(shù)組的push,splice等方法也不會更新dom;
對象里邊的修改:
data () {return{
student: {
name:''},
teach:["李磊"]
}
}//以下操作不會觸發(fā)視圖更新
this.student.name="XXX";
解決辦法:
1 使用set:
this.$set('對象名', key, value); //對象寫法
this.$set(this.teach,0, “韓梅梅”); //數(shù)組寫法
2 使用deep
watch:{
student:{
handler:(n,o)=>{//邏輯處理
},
deep:true}
}
3? 改變原對象或數(shù)組的地址
this.obj = Object.assign({},this.obj,{"sex","man"});
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的vue xunidom_vue的虚拟dom(Virtual DOM )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在c语言中,以r方式不能打开并不存在的文
- 下一篇: hide show vue 动画_(Vu