The difference between v-if and v-show and the problem of v-if partial compilation/uninstallation

1. The difference between v-if and v-show

the difference:

v-if

v-show

means

It controls the visibility of elements by controlling the existence or non-existence of dom nodes;

By setting the display style of the DOM element, block is displayed, and none is hidden;

compilation process

Switching has a process of partial compilation/unloading, and internal event listeners and subcomponents are properly destroyed and rebuilt during the switching process;

Just a simple css-based switch;

compile condition

Is lazy, if the initial condition is false, do nothing; only start partial compilation when the condition becomes true for the first time (after the compilation is cached, and then perform partial unloading when switching);

It is compiled under any condition (whether the condition is true for the first time), and then cached, and the DOM element is retained;

performance consumption

There is a higher switching cost;

Has a higher initial rendering cost;

have to be aware of is:

1. v-show does not support the <template> element!

2. The priority of v-for is higher than that of v-if, and it is not recommended to use it at the same time.

2. Partial compilation/uninstallation of v-if

        When we use v-if, the element will be completely destroyed when v-if is false, and the element will be recreated when it is true, but in fact, vue usually reuses the same element in order to render elements more efficiently. rather than a full re-render.

We may encounter such a scenario:

<template v-if="type === 'username'">
  <label>用户名</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>邮箱</label>
  <input placeholder="Enter your email address">
</template>

1. When the default type value is 'username', a user name input box is displayed on the page;

2. We enter "Zhang San" in the input box, and the content of the user name input box is "Zhang San";

3. Then change the value of type to 'email', the user name input box on the page becomes an email input box; at this time, you will find that the content in the email input box is still "Zhang San".

        When F12 looks at the element, you will find that the content of the label has changed, the content of the placeholder has changed, but the input value has not changed. This is caused by the partial compilation of vue.

        At this time, it involves the issue of virtual DOM. Virtual DOM essentially uses native js objects to describe a DOM node, which is an abstraction of real DOM. When Vue re-renders elements, it will first compare the difference between the two virtual DOMs through the diff algorithm, and then apply the difference between the two virtual DOMs to the real DOM through the pach algorithm to realize the switching of elements.

So what v-if actually destroys and rebuilds is the part with differences.

        Going back to the question just now, the two templates use the same element, so the difference is the content of the label and the placeholder of the input, and the element will not be re-rendered, so the value of the input will not change.

3. Use of Key

        So how do we completely update the elements in the template? At this point, Vue provides a way to express "these two elements are completely independent and do not need to be reused". Just add a key with a unique value:

key is the unique mark in Vnode in Vue, through this key, our diff operation can be more accurate and faster

1. More accurate: because there is no in-place multiplexing with the key, in-place multiplexing can be avoided in the sameNode function a.key === b.key comparison.

2. Faster: Use the uniqueness of the key to generate a map object to obtain the corresponding node, which is faster than the traversal method.

So the scene just now can be changed to

<template v-if="type === 'username'">
  <label>用户名</label>
  <input placeholder="Enter your username" key="username">
</template>
<template v-else>
  <label>邮箱</label>
  <input placeholder="Enter your email address" key="email">
</template>

In this way, when the user name and mailbox are switched, the input will not be reused, because the two inputs have different keys. Note: At this time, the label element will still be reused, because the label element has no key added.

Note: It is not recommended to use index as the key , because no matter how the order of the array is reversed, the index is arranged like 0, 1, 2, which will cause Vue to reuse the wrong old child nodes and do a lot of extra work.

Guess you like

Origin blog.csdn.net/Hello_MrShu/article/details/127107857