key值的作用
key值大多情況下使用在循環語句中,從本質來講主要作用大概有以下兩點:
- 主要用在 Vue 的虛擬 DOM 算法,在新舊 nodes 對比時辨識 VNodes,相當於唯一標識ID。
- Vue 會盡可能高效地渲染元素,通常會復用已有元素而不是從頭開始渲染, 因此使用key值可以提高渲染效率,同理,改變某一元素的key值會使該元素重新被渲染。
key的工作原理
// 因為key值主要使用在虛擬DOM算法,即diff算法中。所以我們在src\core\vdom\patch.js文件中,從源碼級別進行探討
// 先說這里的核心方法patch。這個方法在vue進行update,即將render函數(虛擬DOM生成的函數)轉化為真實DOM的時候執行,里面主要首次渲染創建真實DOM樹,進行虛擬DOM節點直接的對比,以及真實DOM的更新的一系列操作,並且會進行一系列判斷和兼容處理,其中就有對key值的具體使用
// 這個方法主要在patch方法中調用
// 方法名很語義化 sameVnode === 相同虛擬DOM節點
function sameVnode (a, b) {
return (
// 判斷a, b兩個Vnode上的key值是否相等
a.key === b.key && (
(
a.tag === b.tag &&
a.isComment === b.isComment &&
isDef(a.data) === isDef(b.data) &&
sameInputType(a, b)
) || (
isTrue(a.isAsyncPlaceholder) &&
a.asyncFactory === b.asyncFactory &&
isUndef(b.asyncFactory.error)
)
)
)
}
// 在簡單說下patchVnode方法的作用,這個方法會在patch方法里面調用,是直接對比新舊虛擬Vnode節點,也是diff算法真正執行的地方
// 以下代碼在patchVnode方法中
// 在開始進行判斷,符合條件的話就跳出方法,不再進行下面的diff對比
// vnode.key === oldVnode.key判斷雙方是不是同一個組件
if (isTrue(vnode.isStatic) &&
isTrue(oldVnode.isStatic) &&
vnode.key === oldVnode.key &&
(isTrue(vnode.isCloned) || isTrue(vnode.isOnce))
) {
vnode.componentInstance = oldVnode.componentInstance
return
}
結論
在例子中可以看出,對Vnode進行patch的時候會調用sameVnode方法,里面會使用key值是否相等來判斷Vnode是否為同一個。並且在對比過程中作為組件復用的一個判斷條件。
所以key值是在DOM樹進行diff算法時候發揮作用。一個是用來判斷新舊Vnode是否為同一個,從而進行下一步的比較以及渲染。另外一個作用就是判斷組件是否可以復用,是否需要重新渲染。