Home >Web Front-end >Vue.js >What is Key in vue? What is the difference between setting the key and not setting it?

What is Key in vue? What is the difference between setting the key and not setting it?

青灯夜游
青灯夜游forward
2022-05-19 21:09:454256browse

What is Key in vue? The following article will introduce to you the principle of key in vue, and talk about the difference between setting the key and not setting the key. I hope it will be helpful to everyone!

What is Key in vue? What is the difference between setting the key and not setting it?

1. What is Key

Before we begin, let’s restore two actual work scenarios

  • When we use v-for, we need to add key

<ul>
    <li v-for="item in items" :key="item.id">...</li>
</ul>
  • ## to the unit #Use the timestamp generated by

    new Date() as key, and manually force a re-rendering

  • <Comp :key="+new Date()" />
So what is the logic behind this? , What is the function of

key?

In a word

key is the unique ID given to each vnode, and it is also an optimization strategy for diff. It can find the corresponding one more accurately and faster based on the key. vnode node. (Learning video sharing: vue video tutorial)

The logic behind the scene

When we are using

v-for When , you need to add key

    If no key is used, Vue will adopt the in-place restoration principle: minimize the movement of the element, and will try to do its best To a certain extent, patch or reuse elements of the same type in the same appropriate place.
  • If key is used, Vue will record the elements according to the order of keys. If the element that once owned the key no longer appears, it will be directly removed or destroyed
Use

new Date()The generated timestamp is used as key, manually forced to trigger re-rendering

    When the rerender with the new value is used as the key, the new key is Comp appears, then the old key Comp will be removed, and the new key Comp will trigger rendering

2. The difference between setting the key and not setting the key

For example Example:

Create an instance and insert data into the
items array after 2 seconds

<body>
  <div id="demo">
    <p v-for="item in items" :key="item">{{item}}</p>
  </div>
  <script src="../../dist/vue.js"></script>
  <script>
    // 创建实例
    const app = new Vue({
      el: &#39;#demo&#39;,
      data: { items: [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;] },
      mounted () {
        setTimeout(() => { 
          this.items.splice(2, 0, &#39;f&#39;)  // 
       }, 2000);
     },
   });
  </script>
</body>

Without using

key, vue This operation will be performed:

What is Key in vue? What is the difference between setting the key and not setting it?

Analyze the overall process:

    Compare A, A, nodes of the same type, and perform
  • patch , but the data is the same, the operation does not occurdom
  • Compare B, B, nodes of the same type, perform
  • patch, but the data is the same, does not occurdomOperation
  • Compare C, F, nodes of the same type, perform
  • patch, the data is different, domoperation occurs
  • Compare D, C, nodes of the same type, perform
  • patch, the data is different, dom operation occurs
  • Compare E, D, nodes of the same type, perform
  • patch, the data is different, dom operation occurs
  • The loop ends, insert E into
  • DOM
occurs in total 3 updates and 1 insert operation

When using

key: vue will perform the following operation:

    Compare A, A, nodes of the same type, perform
  • patch, but the data is the same, no dom operation occurs
  • Compare B, B, nodes of the same type, perform
  • patch, but the data is the same, no dom operation occurs
  • Compare C, F, nodes of different types
    • Compare E, E, the same type Node, perform
    • patch, but the data is the same, no dom operation will occur
  • Compare D, D, nodes of the same type, perform
  • patch, but the data is the same, no dom operation occurs
  • Compare C and C, nodes of the same type, perform
  • patch, but the data is the same, No dom operation occurs
  • The loop ends, before F is inserted into C
A total of 0 updates and 1 insertion operation occurred

Through the above two small examples, it can be seen that setting

key can greatly reduce the DOM operations on the page and improve the diff efficiency

Can setting the key value definitely improve diff efficiency?

In fact, this is not the case. The document also clearly states that

When Vue.js uses v-for to update the rendered element list, it defaults to "in-place reuse" Strategy. If the order of the data items is changed, Vue will not move the DOM elements to match the order of the data items, but will simply reuse each element here and ensure that it displays each element that has been rendered at a specific index

This default mode is efficient, but it is only suitable for list rendering output that does not rely on subcomponent state or temporary DOM state (for example: form input values)

It is recommended to use it whenever possible ## Provide

key when #v-for, unless traversing the output DOM content is very simple, or deliberately relying on the default behavior to obtain performance improvements<h2 data-id="heading-4"><strong>三、原理分析</strong></h2> <p>源码位置:core/vdom/patch.js </p> <p>里判断是否为同一个<code>key,首先判断的是key值是否相等如果没有设置key,那么keyundefined,这时候undefined是恒等于undefined

function sameVnode (a, b) {
    return (
        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)
            )
        )
    )
}

updateChildren方法中会对新旧vnode进行diff,然后将比对出的结果用来更新真实的DOM

function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {
    ...
    while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
        if (isUndef(oldStartVnode)) {
            ...
        } else if (isUndef(oldEndVnode)) {
            ...
        } else if (sameVnode(oldStartVnode, newStartVnode)) {
            ...
        } else if (sameVnode(oldEndVnode, newEndVnode)) {
            ...
        } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
            ...
        } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
            ...
        } else {
            if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
            idxInOld = isDef(newStartVnode.key)
                ? oldKeyToIdx[newStartVnode.key]
                : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)
            if (isUndef(idxInOld)) { // New element
                createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
            } else {
                vnodeToMove = oldCh[idxInOld]
                if (sameVnode(vnodeToMove, newStartVnode)) {
                    patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)
                    oldCh[idxInOld] = undefined
                    canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)
                } else {
                    // same key but different element. treat as new element
                    createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
                }
            }
            newStartVnode = newCh[++newStartIdx]
        }
    }
    ...
}

(学习视频分享:web前端开发编程基础视频

The above is the detailed content of What is Key in vue? What is the difference between setting the key and not setting it?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete