虛擬dom && diff算法
1.虛擬dom是什么
它是一個Object對象模型,用來模擬真實dom節點的結構
2.虛擬dom的使用基本流程(前四步驟)
1.獲取數據
2.創建vdom
3. 通過render函數解析jsx,將其轉換成 vdom結構
4.將vdom渲染成真實dom
5.數據更改了
6.使用diff算法比對兩次vdom,生成patch對象
7.根據key將patch對象渲染到頁面中改變的結構上,而其他沒有改變的地方是不做任何修改的( 虛擬dom的惰性原則 )
3.diff算法是什么
用來做比對兩次vdom結構
4.diff算法運行結束后,返回是什么
返回一個key
注意:vue是一個mvvm框架,Vue高性能的原因之一就是vdom
深化:Vue vdom 比較 React vdom 有何不一樣?
//需求:有一個變量count的初始值為0,經過一系列的運算,得到10001,然后將結果寫入box中
<div class='box'></div>
<script>
var box = document.querySelect('.box')
var count = 0
//console.time('a')
//for(var i=0;i<10001;i++){
// count++
// box.innerHTML = count //這里操作了10000次dom
//}
//console.timeEnd('a')
///////////////////////////////////////////////////////
console.time('b')
for(var i=0;i<10001;i++){
count++
}
box.innerHTML = count //正常寫法操作一次dom
console.timeEnd('b')
</script>
結論:1.更少的dom操作會更加減少時間花費,減少性能損耗
2.所以我們應該 先操作數據 再去操作dom
3.由以上結論慢慢的前端將一個新的概念引入在框架中 (這個概念就是虛擬dom)
虛擬dom
所謂的virtual dom,也就是虛擬節點
<script>
//1.vdom是什么?
//它是一個Object對象模型,用來模擬真實的dom結構
//需求:vdom如何模擬真實dom,如果將來我想再增加一個li,里面的內容為:你好
<div class='box'>
<ul class='list'>
<li>這里是1903</li>
</ul>
</div>
var list = document.querySelect('.list')
var li = documenr.createElement('li')
li.innerHTML = '你好'
list.appendChild(li) //以上的每一步都操作了dom,真實的dom!
</script>
vdom的使用流程
1.獲取數據
2.創建虛擬dom
//1.獲取數據(ajax,fetch)
var data = {
id:1,
name:'1903'
}
//2.創建vdom
var vdom = {
tag:'div',
attr:{
className:'box'
},
content:[
{
tag:'ul',
content:[
{
tag:'li',
content:data.name //'這里是1903'
}
]
}
]
}
//3.初次渲染vdom(vdom渲染成 真實dom)
var div = document.creatElement('div')
div.calssName = 'box'
var ul = document.creatElement('ul')
var li = document.creatElement('li')
//vue中 使用的是一個叫做jsx語法 + render函數
function render(createElment){
//vu已經封裝好這個方法 就是{{}}可以用的原因
}
//但是我們的網頁結構一般都是很復雜的,這時候我們使用vdom去模擬dom結構,發現vdom這個對象模型太大了,也 //太長了,所以我們想,如果能在js中也能夠書寫dom標簽結構那就好了,所以結合了js+xml搞出了一個新的語法 //糖 jsx,用jsx來模擬vdom
//通過render函數解析jsx,將其解析成vdom結構
//4.將vdom渲染成真實dom
//5.數據更改了,data.name = '駿哥' 又生成虛擬dom(vdom)結構
//在這之中 //使用diff算法用來做比對兩次vdom
//diff算法是比較兩個文件的差異,並將兩個文件的不同之處,將這個不同之處生成一個補丁對象(patch.js)
//diff算法來源后端
//前端將其應用於虛擬dom的diff算法
//vue中將虛擬dom的diff算法放在了patch.js
//使用js來進行兩個對象的比較(vdom 對象模型)
//diff算法是同級比較
//給每一個層級打一個標記,這個標記是一個數字(這個數字就是key)
//6.再通過render函數渲染成真實dom
### 關於diff算法返回的key
<div id='box'>
<ul>
<li v-for = '(item,index) in list' :key = 'item.id'>
<p>{{item.text}}</p>
<div>
<button @click = 'changeStyle'>修改</button>
<button @click = 'remove(index)'>刪除</button>
</div>
</li>
</ul>
</div>
<script>
//id為
new Vue({
el:'#app',
data:{
list:[{
id:1,
text:'敲代碼1'
},
{
id:2,
text:'敲代碼2'
}
]
},
methods:{
changeStyle(e){
//接下來寫的是為了給大家看key的作用,這段代碼不要出現
e.target.parentNode.parentNode.style.background = 'red'
//刪除以后會有上一層的樣式
},
remove(index){
this.list.splice(index,1)
}
}
})
</script>
總結: 虛擬dom的執行步驟
1.獲取數據
2.創建虛擬dom(這一步創建的是jsx語法糖,什么是虛擬dom?就是一個對象,里面模擬了真實dom的數據結構)
3.通過render函數解析jsx(js+xml的語法糖),將其轉化成虛擬dom結構,再將虛擬dom渲染成真實的dom
4.當數據更改之后又會生成一次虛擬dom結構,這是時候就需要diff算法對比兩次虛擬dom,**不同之處**會生成一個patch對象,(由於diff算法進行的是同級比較,而且會返回一個key值)再根據這個key值將patch對象渲染到頁面中改變的結構上。(其他沒有改變的地方是不做修改的,這就是虛擬dom的惰性原則)
