“This is the 20th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

{{time}}

Suppose I have the following data

    const vm = new Vue({
            el: '.box'.data: {
                userinof: [{
                    name: 'Starqin'.age: 22.pro: 'Programmer'.hobby: 'Science fiction movies, electronics'
                }, {
                    name: 'W-js'.age: 23.pro: 'Graphic Designer'.hobby: 'Basketball, car fan'}]}})Copy the code

Next I’ll use V-for to render the above data

The renderings

Is the key in the yellow box in the code above resolved into the DOM by the browser?

The answer is no

Where is the key? What’s the use?

Why is that? Where does Key go?

In fact, the key exists, but the key is used by the vUE layer, placed in the Vue virtual DOM, see the following comparison

Why does vue have this key in its virtual DOM

As we all know, vue performs a Diff algorithm before converting the virtual DOM to the real DOM, comparing the two DOM to render the different parts and leaving the same parts. It is important to note that the comparison here is for nodes, not simply for elements.

Vue is compared by the key value on the element, as shown in the figure below

When vue makes a comparison and finds that there is no key=2 in the original virtual DOM, it directly renders the DOM named Zhang SAN as a real DOM

In other words, the key here is the key that supports the DIFF algorithm. Since it is so critical, can we not write the key here?

The answer is yes, if we do not write the key, then vUE will default to the index value of v-for as the key value, whether we write or not, the virtual DOM must have the key attribute.

What bugs occur when key is an index

Since Vue generates a key by default, why does someone keep telling me to write a key?

Now I need to dynamically insert the zangsan object in front of the example above (insert a member in front of Starqin) and render it to the page

<body>
    <div class="box">
        <button @click="addUser">Click me add Joe</button>
        <div class="userbox" v-for="(v,i) in userinof" :key="i">
            <p>Name: {{v.n ame}}</p>
            <p>Hobbies: {{v.h obby}}</p>
            <p>Age: {{says v. ge}}</p>
            <p>Career: {{Valerie plame ro}}</p>
            <input type="text">
        </div>
    </div>

    <script>
        const vm = new Vue({
            el: '.box'.data: {
                userinof: [{
                    name: 'Starqin'.age: 22.pro: 'Programmer'.hobby: 'Science fiction movies, electronics'
                }, {
                    name: 'W-js'.age: 23.pro: 'Graphic Designer'.hobby: 'Basketball, car fan'}].// This is not an element in the userinof array, but an object under data
                zansan: {
                    name: 'Joe'.age: 55.pro: 'Home squat university distinguished professor of braggart expert'.hobby: 'brag'}},methods: {
                addUser() {
                   this.userinof.unshift(this.zansan)
                }
            },
        })
    </script>
</body>
Copy the code

See the render page diagram

Notice that I’ve added a button here, as well as a new one in the templateinputBox, when I click on this button, will put the above datazansanObject append touserinofThe beginning of an array. Also notice the values in the two input fields before clicking this button,Starqin in the input box, w-js in the input box w-js

When I click the button, the application will look like this

Careful you are not found, I input the text of the box dislocation. Why is that? Is this a BUG in vue rendering pages? It’s not. Let’s refocus our attentionkeyFor example, see the virtual DOM comparison diagram

The reason for the above BUG is that we inserted a Zangsan object in front of the original array, which causes Starqin with index 0 and W-js with index 1 to become Starqin with index 1 and W-sj with index 2. Please see the following figure for index changes

In addition, the array index is used as the key value. As a result, the old and new virtual DOM depend on the key value. When making comparison, we find that the nodes in the red box on the virtual DOM comparison diagram are different from the old virtual DOM, so we re-render them, while the nodes in the green box are the same, so we directly reuse them and finally form the aboveinputThe frame is misplaced

Solve the Key index BUG

How to fix this BUG?

In fact, to solve this problem is very simple, we just need to assign the unique value of the data to the key can perfect solve such a BUG, for example, I assign the user name as the unique value to the part of the code after the key modification

<div class="box">
        <button @click="addUser">Click me add Joe</button>
        <div class="userbox" v-for="(v,i) in userinof" :key="v.name">
            <p>Name: {{v.n ame}}</p>
            <p>Hobbies: {{v.h obby}}</p>
            <p>Age: {{says v. ge}}</p>
            <p>Career: {{Valerie plame ro}}</p>
            <input type="text">
        </div>
    </div>
Copy the code

Click the button after modificationProblem solved perfectly \

Why is that? Please see below

At this point, the binding key values of the old and new virtual DOM will not change, forming a one-to-one correspondence relationship. During comparison, it is found that there is no triple key value in the old virtual DOM, so a new element is directly rendered on the old real DOM.

Conclusion:

  1. If the data has a unique identifier, the key value must be that unique identifier.
  2. The existence of key is to better support the DIFF algorithm of Vue