Maison >interface Web >Voir.js >Une analyse approfondie des valeurs clés dans Vuejs

Une analyse approfondie des valeurs clés dans Vuejs

青灯夜游
青灯夜游avant
2021-06-02 14:14:492647parcourir

Cet article vous présentera les connaissances pertinentes sur les valeurs clés dans Vuejs. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Une analyse approfondie des valeurs clés dans Vuejs

À partir de l'article précédent

J'ai écrit un article il y a quelques jours, sortable.js - Problème de mise à jour des données Vue À cette fois-là, je n'ai analysé les données que du point de vue d'un rafraîchissement forcé, et je n'ai pas trouvé le vrai « coupable ».

Merci beaucoup pour quelqu'un qui m'a aidé à souligner que c'est peut-être la Vue valeur de key qui provoque un rendu incorrect des données. À partir de là, j’ai fait d’autres tentatives. [Recommandation associée : "Tutoriel vue.js"] Une utilisation incorrecte de la

clé - utilisez index comme key

Je ne sais pas ce que vous j'écrisv-for, vais-je utiliser directement index comme valeur key Oui, j'avoue que je le ferai, je dois dire, ce n'est vraiment pas une bonne habitude.

Sur la base de l'article précédent, nous utilisons toujours sortable.js comme exemple pour discuter. Ce qui suit est le code de base, où la valeur de arrData est [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(&#39;sort&#39;)
    var sortable = new Sortable(el, {
      onEnd: (e) => {
        const tempItem = this.arrData.splice(e.oldIndex, 1)[0]
        this.arrData.splice(e.newIndex, 0, tempItem)
      }
    })
  }

Bien sûr, il n'y aura aucun problème avec le rendu des données au début

Une analyse approfondie des valeurs clés dans Vuejs

Bon, regardons les opérations suivantes :

Une analyse approfondie des valeurs clés dans Vuejs

Comme vous je peux voir, je le ferai. Lorsque 3 est glissé au-dessus de 2, les données ci-dessous deviennent 1342, mais celle affichée ci-dessus est toujours 1234. Ensuite, lorsque j'ai fait glisser la quatrième position vers la troisième position, les données ci-dessous ont également pris effet, mais les données ci-dessus semblaient toutes foirées. Super, nous avons recréé la scène du crime.

Ensuite, j'ai changé la valeur liée key Parce que l'exemple ici est assez spécial, nous pensons que les valeurs de item sont différentes

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

Regardez l'effet :

Une analyse approfondie des valeurs clés dans Vuejs

Oui, à ce moment, les données sont complètement synchronisées avec la vue.

Pourquoi ?

Premier coup d'œil à l'introduction de key dans la documentation officielle

Les éléments enfants avec le même élément parent doivent avoir des clés uniques. Les clés en double entraîneront des erreurs de rendu.

provoque l'erreur de rendu ci-dessus car notre valeur key n'est pas unique. Par exemple, la valeur key ci-dessus modifiera la valeur d'origine de chaque élément après avoir ajusté l'ordre du tableau <.> les valeurs ont changé, entraînant des erreurs de rendu. key

Tirons d'abord une conclusion.

Il existe des dangers cachés à utiliser comme valeur de index à moins que vous ne puissiez garantir que key peut toujours être utilisé comme identifiant unique index

A quoi sert la valeur clé ?

Après

, si nous n'écrivons pas vue2.0, il rapportera key, ce qui signifie que le fonctionnaire veut que nous écrivions warning valeur Oui, alors quel rôle key joue-t-il dans key ? vue

Les performances peuvent-elles être améliorées sans utiliser de clés La réponse est oui ! Peut!

Regardez d'abord l'explication officielle :

Si les clés ne sont pas utilisées, Vue utilisera un algorithme qui minimise les éléments dynamiques et essaiera de réparer/réutiliser autant que possible les éléments du même type. que possible. À l'aide de key, il réorganise l'ordre des éléments en fonction des changements de clé et supprime les éléments là où la clé n'existe pas.

Par exemple, si un tableau [1,2,3,4] devient [2,1,3,4], alors la valeur sans

prendra un "sur place" Stratégie de mise à jour", voir l'image ci-dessous. Elle ne déplace pas la position du nœud de l'élément, mais modifie directement l'élément lui-même, économisant ainsi quelques performances key

Une analyse approfondie des valeurs clés dans Vuejs

Et pour les éléments avec

valeurs, sa mise à jour La méthode est illustré dans la figure ci-dessous. Comme vous pouvez le constater, il s'agit ici d'une opération de suppression/ajout au DOM, relativement gourmande en performances. key

Une analyse approfondie des valeurs clés dans Vuejs

n'a en fait pas Les performances sont meilleures, pourquoi devons-nous apporter la clékey Regardons d'abord un exemple Le noyau. Le code est le suivant. Voici une imitation d'un commutateur La fonction de , c'est-à-dire que l'onglet1 à changer est 1,2,3,4. tab2 est 5,6,7,8. Il existe une fonction permettant de définir la couleur de police du premier élément sur rouge en cliquant dessus. tab

那么当我们点击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(&#39;item&#39;)[0].style.color = &#39;red&#39;
      }

Une analyse approfondie des valeurs clés dans Vuejs

这就超出了我们的预期了,也就是官方文档所说的,默认模式指的就是不带 key 的状态,对于依赖于子组件状态或者临时 DOM 状态的,这种模式是不适用的。

这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。

我们来看带上 key 之后的效果

Une analyse approfondie des valeurs clés dans Vuejs

这就是官方文档之所以推荐我们写 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 中相对应的节点。

更多编程相关知识,请访问:编程视频!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer