1. 程式人生 > 程式設計 >Vue頁面渲染中key的應用例項教程

Vue頁面渲染中key的應用例項教程

引言

在前端專案開發過程中,el-table展示的結果列使用元件形式引入,其中某些欄位通過:formatter方法轉碼,結果欄位的欄位顯示/隱藏控制也使用元件形式引入,前端在控制欄位顯示屬性時,發現碼值轉換及欄位資訊展示均有問題。

問題分析

通過閱讀程式碼結構,發現el-table-column通過template迴圈生成,由於template的作用是模板佔位符,可幫助我們包裹元素,但在迴圈過程當中,template不會被渲染到頁面上。有關表格資料渲染中key的作用如下:

  • key作為一個DOM節點的標識值,結合Diff演算法可以實現對節點的複用。(key相同的節點會被複用);
  • 只有當key(或其他導致isSameNode判斷為false)發生改變時,才會觸發節點的重新渲染。否則Vue將會複用之前的節點,通過改變節點的屬性來實現節點的更新。

同時,template標籤不支援:key屬性,

注意: vue例項繫結的元素內部的template標籤不支援v-show指令,即v-show="false"對template標籤來說不起作用。但是此時的template標籤支援v-if、v-else-if、v-else、v-for這些指令。

解決方法

既然template標籤不支援key屬性,可通過在el-table-column標籤加入:key="Math.random()"屬性,這個key屬性是vue自帶的特殊屬性,主要用在 Vue 的虛擬 DOM 演算法,在新舊 nodes 對比時辨識 VNodes,依次來提升頁面渲染效能。如果不更新這個key的話,顯示/隱藏列的時候,部分DOM不會重新渲染,導致table變化時候內容錯亂。

拓展閱讀

一、key的作用

前文已經講到,作為一個DOM節點的標識值,結合Diff演算法可實現對節點的複用。(key相同的節點會被複用。)

只有當key(或其他導致isSameNode判斷為false)發生改變時,才會觸發節點的重新渲染。否則Vue將會複用之前的節點,通過改變節點的屬性來實現節點的更新。那麼,key使用id與index的區別又是什麼呢?

二、key使用id與index的區別

不推薦使用index作為key,因為這種做法會導致某些節點被錯誤地原地複用,具體如下:

  • 效能損耗:列表渲染時會導致變動項往後的所有列表節點(內容)的更新(相當於key沒發揮作用)。
  • 出現錯誤:某些節點在錯誤的位置被複用。(例如當列表項中使用到複選框時)

效能損耗

列表渲染時會導致變動項往後的所有列表節點(內容)的更新(相當於key沒發揮作用)

需要注意的是,變動項往後的所有列表節點的更新本質是節點屬性的更新,節點本身會被複用。

<!-- 測試程式碼 -->
<template>
 <div>
 <div v-for="(item,index) in arr" :key="index 或 item.id">
  {{item.data}}
 </div>
 </div>
</template>

<script>
export default {
 name: 'HelloWorld',data(){
 return {
  arr: Array.from({length: 10000},(v,i) => {return {id: i,data: i}})
 }
 },mounted(){
 setTimeout(()=>{
  /* 
  1. this.shiftArr()	// 刪除首項
  或
  2. this.unShiftArr()	// 在首部插入新項
  */
 },1000)
 },methods: {
 shiftArr(){
  this.arr.shift();
 },unshiftArr(){
  this.arr.unshift({id: -1,data: -1});
 }
 }
}
</script>

上邊的例子很簡單,就是v-for渲染一個長度為10000的列表,然後在Vue mounted 1s後,執行一個刪除列表首項或在列表頭插入新項,觀察兩種key繫結的具體頁面更新開銷。

頁面開銷使用chrome的performance選項卡來測算

刪除列表首項

Vue頁面渲染中key的應用例項教程

列表頭 unshift 新元素

Vue頁面渲染中key的應用例項教程

出現錯誤

某些節點在錯誤的位置被複用。(例如當列表項中使用到複選框時)

<!-- 測試程式碼 -->
<template>
 <div>
 <button @click="test">刪除列表第一項</button>
 <div v-for="(item,index) in arr" :key="index 或 item.id">
  <input type="checkbox" />
  {{item.data}}
 </div>
 </div>
</template>

<script>
export default {
 name: 'HelloWorld',data(){
 return {
  arr: Array.from({length: 5},methods: {
 test(){
  this.arr.shift();
 }
 }
}
</script>

總結

到此這篇關於Vue頁面渲染中key的應用的文章就介紹到這了,更多相關Vue頁面渲染key的應用內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!