6

Youda clearly pointed out in the vue 2.x document: It is recommended to provide the key attribute when using v-for as much as possible, unless it is very simple to traverse the output DOM content, or deliberately rely on the default behavior for a performance boost.

You Da's suggestion put it bluntly:

If the index can be used as the key, then the bottom layer will help you pass it in, so why bother you? Don't use index as key

So what is :key for? When Vue.js is updating the rendered list of elements with v-for, it defaults to the in -place reuse strategy. What does it mean?

Let's explore together

diff algorithm

image.png

Simply put, it is the comparison of 新旧虚拟dom . If there is a difference, the new one shall prevail, and then insert it into the real DOM and re-render it.

The role of the key

image.png

In a word: key is mainly to compare whether each node in the virtual DOM is the same node more efficiently;

Take a simple example

The triplets are in a row, how do you know who's the boss?

How can you tell the difference if the eldest brother suddenly changes positions with the eldest third?

Put up a card for them, write the eldest, the second, and the third.

That way you won't be mistaken. key is the role.

Manage state by key

Vue defaults to updating the list of elements rendered by v-for according to the "in-place update" strategy. When the order of data items changes, Vue doesn't move the order of DOM elements with it, but instead updates each element in-place to ensure they render at the index position they originally specified.

The default mode is efficient, but only works if the list rendering output does not depend on child component state or temporary DOM state (such as form input values) .

To give Vue a hint so that it can keep track of each node's identity and thus reuse and reorder existing elements, you need to give each element's corresponding block a unique key attribute:

In the absence of a key, Vue will use an algorithm that minimizes movement of elements and update/reuse elements of the same type in-place whenever possible. If a key is passed, the elements will be rearranged according to the changing order of the key, and will always remove/destroy elements whose key does not already exist.

Child elements under the same parent element must have unique keys . Duplicate keys will cause rendering exceptions

Efficiency & Bug

Speaking of which, some people think it's simply a matter of efficiency.

Indeed: setting the key makes the diff more efficient, but is it just 重绘重排 ?

The answer is 否定 of

If it's just inefficiency, in elements with very few operations, it doesn't hurt either.

However, the problem of using index is much more troublesome

image.png

image.png

 <div id="app">
    <Child v-for="item,i in array" :text="item" @delete="remove(i)"/>
</div>

data() {
    return {
      array: [1, 2, 3]
    };
},
methods: {
    remove(i) {
      this.array.splice(i, 1);
    }
}
At this point, the role of the key is to 复用 . It is precisely because it will be 复用 , so using index as the key will appear 复用错误 The problem, causing unexpected bug

Summarize

The most simple and convenient is: use the id in the database

What if there is no id in the return value

  • Create a 自增id函数 , which increments by one with each call
  • Use uuid库

Alright, that's it for now. Looking forward to your one-click triple


高志鹏
171 声望16 粉丝

努力强大自己,竭力去做一个伟大的产品