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)(損耗一點性能)
- 原本準備生成的真實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可以精準判斷兩個節(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)文章
基于Vue中點擊組件外關(guān)閉組件的實現(xiàn)方法
下面小編就為大家分享一篇基于Vue中點擊組件外關(guān)閉組件的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03
純前端使用Vue3上傳文件到minio文件服務(wù)器(粘貼可直接用)
vue是目前最流行的前端框架,下面這篇文章主要給大家介紹了關(guān)于純前端使用Vue3上傳文件到minio文件服務(wù)器的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-04-04
vue3中watch監(jiān)聽不同數(shù)據(jù)源的方法總結(jié)
這篇文章主要為大家詳細介紹了vue3中watch監(jiān)聽不同數(shù)據(jù)源的常用方法,文中的示例代碼講解詳細,具有一定的借鑒價值,大家可以根據(jù)自己的需要進行選擇2026-03-03
基于Vue3實現(xiàn)點擊Tab平滑滾動并吸頂效果的完整代碼
在現(xiàn)代 Web 應(yīng)用開發(fā)中,良好的用戶體驗至關(guān)重要,本文將深入剖析一個常見的交互需求:點擊頁面 Tab 欄時,頁面平滑滾動至該 Tab 區(qū)域,并使其吸附在頂部導(dǎo)航欄下方的效果,需要的朋友可以參考下2026-02-02

