First, the role of key

As the identity value of a DOM node, the node can be reused with Diff algorithm. (Nodes with the same key will be reused.) Rerendering of the node is triggered only if the key(or something else that causes isSameNode to judge false) changes. Otherwise, Vue will reuse the previous node and update the node by changing its properties.

Key use id and index

It is not recommended to use index as the key because this can cause some nodes to be mistakenly reused in situ, as follows:

  • Performance cost: List rendering causes all list nodes (content) to be updated after the change item (equivalentkeyIt didn’t work).
  • Error: some nodes were multiplexed at the wrong location. (for example when checkboxes are used in list items)

Performance loss

– List rendering will cause all list nodes (contents) to be updated after the changed item (equivalent to the key not being used)

It should be noted that all list nodes after the change item are essentially updates of node attributes, and the node itself will be reused.

<! <template> <div> <div v-for="(item, index) in arr" :key="The index or 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 () // delete the first item or 2. This.unshiftarr (
    }, 1000)
  },
  methods: {
    shiftArr(){
      this.arr.shift();
    },
    unshiftArr(){
      this.arr.unshift({id: - 1, data: - 1});
    }
  }
}
</script>
Copy the code

The above example is very simplev-forRender a list with a length of 10000, then in VuemountedAfter 1s, either delete the first item of the list or insert a new item at the head of the listkeyThe specific page update overhead of the binding.

Page overhead is measured using chrome’s Performance TAB

Delete the first item in the list



List header unshift new element

There is an error

Some nodes are being multiplexed at the wrong location. (for example when checkboxes are used in list items)

<! <template> <div> < button@click ="test"</button> <div v-for="(item, index) in arr" :key="The index or item. Id">
      <input type="checkbox" />
      {{item.data}}
    </div>
  </div>
</template>

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

useindexAs akey(Check box was mistakenly reused)



useidAs akey