91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vuejs中key值的作用是什么

發布時間:2021-06-02 15:52:39 來源:億速云 閱讀:401 作者:Leah 欄目:編程語言

這篇文章給大家介紹Vuejs中key值的作用是什么,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

key 的一個錯誤使用——使用 index 作為 key

不知道你在寫 v-for 的時候,會不會直接使用 index 作為它的 key 值,是的,我承認我會,不得不說,這真的不是一個好習慣。

根據上篇文章,我們還是用 sortable.js 作為例子討論。以下是核心代碼,其中 arrData 的值為 [1,2,3,4]

<div id="sort">
  <div v-for="(item,index) in arrData" :key="index" >
    <div>{{item}}</div>
  </div>
</div>
  mounted () {
    let el = document.getElementById('sort')
    var sortable = new Sortable(el, {
      onEnd: (e) => {
        const tempItem = this.arrData.splice(e.oldIndex, 1)[0]
        this.arrData.splice(e.newIndex, 0, tempItem)
      }
    })
  }

當然一開始的時候,數據渲染肯定是沒有問題的

Vuejs中key值的作用是什么

好了,我們來看下以下的操作:

Vuejs中key值的作用是什么

可以看到,我將3拖到2上面的時候,下面的數據變成了 1342,但是上面視圖的還是1234。然后我第四位置拖到第三位置的時候,下面的數據也是生效的,但是上面的數據似乎全部錯亂了。很好,我們重現了案發現場。

接著我改了綁定的 key 值,因為這里的例子比較特殊,我們就認為 item 的值都不相同

<div id="sort">
  <div v-for="(item,index) in arrData" :key="item" >
    <div>{{item}}</div>
  </div>
</div>

再看效果:

Vuejs中key值的作用是什么

是的,這個時候數據就完全跟視圖同步了。

為什么?

先看官方文檔中 key 的一句介紹

有相同父元素的子元素必須有獨特的 key。重復的 key 會造成渲染錯誤。

之所以會造成上面渲染錯誤的情況,是因為我們的 key 值不是獨特的,比如上面的 key 值,在調整數組順序后就每一項原來的  key 值都變了,所以導致了渲染錯誤。

我們先來得出一個結論,index 作為 key 值是有隱患的,除非你能保證 index 始終能夠能夠作為一個唯一的標識

key 值到底有什么用

vue2.0 之后,我們不寫 key 的話,就會報 warning,那也就是說官方是希望我們寫 key 值的,那么 key 到底在 vue 中扮演了什么樣的角色?

不使用 key 可以提高性能么答案是,是的!可以!

先看官方解釋:

如果不使用 key,Vue 會使用一種最大限度減少動態元素并且盡可能的嘗試修復/再利用相同類型元素的算法。使用 key,它會基于 key 的變化重新排列元素順序,并且會移除 key 不存在的元素。

比如現在有一個數組 [1,2,3,4]變成了[2,1,3,4],那么沒有 key 的值會采取一種“就地更新策略”,見下圖。它不會移動元素節點的位置,而是直接修改元素本身,這樣就節省了一部分性能

Vuejs中key值的作用是什么

而對于有 key 值的元素,它的更新方式如下圖所示。可以看到,這里它對 DOM 是移除/添加的操作,這是比較耗性能的。

Vuejs中key值的作用是什么

竟然不帶 key 性能更優,為何還要帶 key先來看一個例子,核心代碼如下,這里模仿一個切換 tab 的功能,也就是切換的tab1 是1,2,3,4。tab2 是 5,6,7,8。其中有設置了一個點擊設置第一項字體色為紅色的功能。

那么當我們點擊tab1將字體色設置成紅色之后,再切換到 tab2,我們預期的結果是我們第一項字體的初始顏色而不是紅色,但是結果卻還是紅色。

<div id="sort">
  <button @click="trunToTab1">tab1</button>
  <button @click="trunToTab2">tab2</button>
  <div v-for="(item, index) in arrData">
    <div @click="clickItem(index)" class="item">{{item}}</div>
  </div>
</div>
      trunToTab1 () {
        this.arrData = [1,2,3,4]
      },
      trunToTab2 () {
        this.arrData = [5,6,7,8]
      },
      clickItem () {
        document.getElementsByClassName('item')[0].style.color = 'red'
      }

Vuejs中key值的作用是什么

這就超出了我們的預期了,也就是官方文檔所說的,默認模式指的就是不帶 key 的狀態,對于依賴于子組件狀態或者臨時 DOM 狀態的,這種模式是不適用的。

這個默認的模式是高效的,但是只適用于不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出。

我們來看帶上 key 之后的效果

Vuejs中key值的作用是什么

這就是官方文檔之所以推薦我們寫 key 的原因,根據文檔的介紹,如下:

使用 key,它會基于 key 的變化重新排列元素順序,并且會移除 key 不存在的元素。 它也可以用于強制替換元素/組件而不是重復使用它。當你遇到如下場景的時候它可能會很有用:

  • 完整地觸發組件的生命周期鉤子

  • 觸發過渡

那么 Vue 底層 key 值到底是怎么去做到以上的功能?我們就得聊聊 diff 算法以及虛擬 DOM 了。

key 在 diff 算法中的作用

這里我們不談 diff 算法的具體,只看 key 值在其中的作用。(diff 算法有機會我們再聊)

vue 源碼中 src/core/vdom/patch.js

if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
        idxInOld = isDef(newStartVnode.key)
          ? oldKeyToIdx[newStartVnode.key]
          : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)

我們整理一下代碼塊:

  // 如果有帶 key
  if (isUndef(oldKeyToIdx)) {
    // 創建 index 表
    oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
  }
  if (isDef(newStartVnode.key)) {
    // 有 key ,直接從上面創建中獲取
    idxInOld = oldKeyToIdx[newStartVnode.key]
  } else {
    // 沒有key, 調用 findIdxInOld
    idxInOld = findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx);
  }

那么最主要還是 createKeyToOldIdxfindIdxInOld 兩個函數的比較,那么他們做了什么呢?

function createKeyToOldIdx (children, beginIdx, endIdx) {
  let i, key
  const map = {}
  for (i = beginIdx; i <= endIdx; ++i) {
    key = children[i].key
    if (isDef(key)) map[key] = i
  }
  return map
}
 function findIdxInOld (node, oldCh, start, end) {
    for (let i = start; i < end; i++) {
      const c = oldCh[i]
      if (isDef(c) && sameVnode(node, c)) return i
    }
  }

我們可以看到,如果我們有 key 值,我們就可以直接在 createKeyToOldIdx 方法中創建的 map 對象中根據我們的 key 值,直接找到相應的值。沒有 key 值,則需要遍歷才能拿到。相比于遍歷,映射的速度會更快。

key 值是每一個 vnode 的唯一標識,依靠 key,我們可以更快的拿到 oldVnode 中相對應的節點。

關于Vuejs中key值的作用是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鸡东县| 宁国市| 鲁甸县| 卢湾区| 乌兰县| 昭通市| 马山县| 长丰县| 宽城| 安乡县| 阿拉善左旗| 肇庆市| 胶州市| 涟水县| 息烽县| 新晃| 和龙市| 元朗区| 沁水县| 东兴市| 梅州市| 正宁县| 巫溪县| 涪陵区| 湄潭县| 宁阳县| 鹿邑县| 双城市| 克拉玛依市| 库伦旗| 喀什市| 桂平市| 巴彦县| 仁怀市| 朝阳市| 博客| 凤凰县| 乌兰浩特市| 曲靖市| 虎林市| 胶南市|