vue的虛擬DOM使用方式
1. vue的虛擬DOM (VNode VDOM)
虛擬DOM就是一個JS對象,用它來描述真實DOM
1.1 為什么 virtual dom 是好用的
demo1: 多次執(zhí)行dom操作
<body> <div style="width: 200px; border:1px solid #000;"></div> <script> var box = document.querySelector('.box'); var count = 0; console.time('a') for (var i = 1; i < 10002; i++) { count = i box.innerHTML += count } console.timeEnd('a') </script> </body>
demo2: 只執(zhí)行一次dom操作
var box = document.querySelector( '.box' ) ; var num = “0” console.time( 'b' ) for ( var i = 1 ; i < 10002 ; i ++ ){ num += i } box.innerHTML = num console.timeEnd( 'b' )
- 比較運行時間:得到結(jié)論
- 越多的真實dom操作,越損耗性能
- 操作數(shù)據(jù)要大大的減少性能損耗,提高渲染效率
1.2 更新DOM的三種方案的區(qū)別
第一種更新DOM的方案
- 1、data數(shù)據(jù)
- 2、模板
- 3、數(shù)據(jù) + 模板 結(jié)合,生成真實的DOM -> 視圖
- 4、data發(fā)生了變化
- 5、數(shù)據(jù) + 模板 結(jié)合,生成真實的DOM,替換原始的DOM
缺陷:
- 1、第一次生成了完整的DOM片段
- 2、第二次生成了完整的DOM片段
- 3、第二次的DOM替換第一次的DOM,非常耗費性能
第二種更新DOM的方案
- 1、data數(shù)據(jù)
- 2、模板
- 3、數(shù)據(jù) + 模板 結(jié)合, 生成真實的DOM -> 視圖
- 4、data發(fā)生變化
- 5、數(shù)據(jù) + 模板 結(jié)合,生成真實的DOM,并不直接替換原始的DOM
- 6、新的DOM(DocumentFragment)和原始的DOM做比對,找差異
- 7、找出變化 (比如input框發(fā)生了變化)
- 8、只用新的DOM中的input元素,替換掉老的DOM中input元素
缺陷:
- 雖然DOM只是局部替換,但是在比對時候的計算是比較耗費性能的,因此,性能的提升并不明顯
第三種使用虛擬DOM的方案
- 1、讀取data數(shù)據(jù)
- 2、讀取模板
- 3、數(shù)據(jù) + 模板 生成虛擬DOM(虛擬DOM就是一個JS對象,用它來描述真實DOM)(損耗一點性能)
- 原本準(zhǔn)備生成的真實dom:<div id=“abc”><span> hello world </span></div>
- 虛擬DOM:['div', {id: 'abc‘}, ['span', '', 'hello world']]
- 4、用虛擬DOM的結(jié)構(gòu)生成真實的DOM -> 視圖顯示 (用document.createElement可基于虛擬DOM生成真實DOM) 真實DOM:<div id='abc'><span></span></div>
- 5、當(dāng)data發(fā)生了變化
- 6、數(shù)據(jù) + 模板 生成新的虛擬DOM:['div', {id: 'abc'}, ['span', '', 'hi world11111']]
- 7、比較原始虛擬DOM和新的虛擬DOM的區(qū)別(diff算法),比如找到的區(qū)別是span中的內(nèi)容發(fā)生了變化(極大提升了性能)
- 8、將變化的部分生成真實DOM(用createElement可基于虛擬DOM生成真實DOM)
- 9、將不同部分渲染在頁面(直接操作DOM,改變span中的內(nèi)容)
虛擬DOM優(yōu)點:
- 1、性能提升了
- 2、它使得跨端應(yīng)用得以實現(xiàn),比如:React Native (RN)
V(virtual虛擬)DOM的渲染流程、虛擬DOM的原理
- 1.獲取數(shù)據(jù)
- 2.根據(jù)數(shù)據(jù)創(chuàng)建VDOM 虛擬DOM就是一個JS對象,用它來描述真實DOM(相當(dāng)于給對象賦值)
- 3.根據(jù)VDOM渲染生成真實DOM ( 根據(jù)createElement(‘DIV’) )
- 4.當(dāng)數(shù)據(jù)發(fā)生改變后,又會生成新的VDOM
- 5.通過 diff 算法 比對 多次生成的 VDOM, 將不同的內(nèi)容比對出來,然后再進行真實DOM渲染,一樣的內(nèi)容是不會進行渲染的,這就是VDOM 的 ‘就地復(fù)用’ | ‘惰性原則’
2. vue中key值的作用
key是虛擬dom對象的標(biāo)識 在更新時key起著極其重要的作用
2.1 理解key值的作用
當(dāng)狀態(tài)數(shù)據(jù)發(fā)生變化時,vue會根據(jù)【新數(shù)據(jù)】生成【新的虛擬dom】
隨后vue進行【新的虛擬dom】與【舊的虛擬dom】的diff比較 比較規(guī)則如下:
a. 如果舊虛擬dom找到了與新虛擬dom相同的key
- (1)若舊虛擬dom中內(nèi)容沒變,直接使用之前的真實dom
- (2)若舊虛擬dom中內(nèi)容發(fā)生了改變,則生成新的真實dom 隨后替換掉頁面中的真實dom
b. 如果舊虛擬dom未找到與新虛擬dom相同的key 根據(jù)數(shù)據(jù)創(chuàng)建新的真實dom隨后渲染到頁面
2.2 使用index索引值作為key值
數(shù)據(jù):
[{ id: 1, name: '小李', age: 18 }, { id: 2, name: '小張', age: 19 }]
初始的虛擬dom
<li key=0>小李------18 <input type="text" /></li> <li key=1>小張------19 <input type="text" /></li>
更新后的數(shù)據(jù)
{ id: 3, name: '小王', age: 20 }, { id: 1, name: '小李', age: 18 }, { id: 2, name: '小張', age: 19 }
更新數(shù)據(jù)后的虛擬dom
<li key=0>小王------20 <input type="text" /></li> <li key=1>小李------18 <input type="text" /></li> <li key=2>小張------19 <input type="text" /></li>
2.3 使用id索引值作為key值
數(shù)據(jù):
[{ id: 1, name: '小李', age: 18 }, { id: 2, name: '小張', age: 19 }]
初始的虛擬dom
<li key=1>小李------18 <input type="text" /></li> <li key=2>小張------19 <input type="text" /></li>
更新后的數(shù)據(jù)
{ id: 3, name: '小王', age: 20 }, { id: 1, name: '小李', age: 18 }, { id: 2, name: '小張', age: 19 }
更新數(shù)據(jù)后的虛擬dom:
<li key=3>小王------20 <input type="text" /></li> <li key=1>小李------18 <input type="text" /></li> <li key=2>小張------19 <input type="text" /></li>
key的作用主要是為了高效的更新虛擬DOM, 其原理是vue在數(shù)據(jù)更新過程中通過key可以精準(zhǔn)判斷兩個節(jié)點是否是同一個,從而避免頻繁更新不同元素,使得整個更新過程更加高效,減少DOM操作量,提高性能。
另外,若不設(shè)置key還可能在列表更新時引發(fā)一些隱蔽的bug。
vue中在使用相同標(biāo)簽名元素的過渡(transition組件)切換時,也會使用到key屬性,其目的也是為了讓vue可以區(qū)分它們,否則vue只會替換其內(nèi)部屬性而不會觸發(fā)過渡效果。
3. v-if 和v-for為什么不能用在同一個元素
v-for比v-if優(yōu)先,即每一次都需要遍歷整個數(shù)組,影響速度。
<div v-for="(fileMsg,index) in fileMsgList" :key="fileMsg.id" v-if="index < 2" > <sys-file-layout :fileMsg="fileMsg"></sys-file-layout> </div>
以上代碼,如果有100條數(shù)據(jù),雖然顯示兩條,但需要遍歷100次,因為v-for優(yōu)先
更好的解決方案: 是用computed先獲取符合條件的數(shù)據(jù),再進行遍歷
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Vue2+Echarts實現(xiàn)多種圖表數(shù)據(jù)可視化Dashboard(附源碼)
本篇文章主要介紹了詳解Vue2+Echarts實現(xiàn)多種圖表數(shù)據(jù)可視化Dashboard(附源碼),具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03vue3 watch和watchEffect的使用以及有哪些區(qū)別
這篇文章主要介紹了vue3 watch和watchEffect的使用以及有哪些區(qū)別,幫助大家更好的理解和學(xué)習(xí)vue框架,感興趣的朋友可以了解下2021-01-01