Vue basic self inspection - conditional rendering and list rendering

Posted by bryanptcs on Sat, 06 Nov 2021 04:28:53 +0100

  1. What is the difference between v-if and v-show?
  2. Why can't v-if and v-for be used together?
  3. What is the role of key in v-for?

1 v-if and v-show

1.1 function

Are used to control the display and hiding of elements

1.2 control how elements are displayed and hidden

v-if controls the creation and destruction of elements on the virtual DOM tree. Vue's response system will update the actual DOM according to the virtual DOM tree, so as to indirectly control the display and concealment of elements on the actual dom

v-show makes the element hidden by adding the style display:none to the element

1.3 initial rendering comparison

v-if is inert. If the initial rendering condition is false, do nothing; Compilation will start only if the condition is true

v-show regardless of the initial rendering conditions, the elements are always compiled and retained, and then switched through CSS according to the conditions

1.4 comparison of switching consumption

If you switch display and hide frequently, v-if will frequently create and destroy elements, while v-show only switches styles

Therefore, the switching consumption of v-if is higher

1.5 comparison of usage scenarios

If the display and hiding of the element is fixed at the beginning and will not change again, use v-if

If the element needs to switch between explicit and implicit frequently, use v-show

1.6 others

  • v-if can be used with template, but v-show cannot
  • v-if can be used with v-else, and v-show has no special syntax

2 v-if and v-for

2.1 reasons why V-IF and v-for cannot be used at the same time

Why not use v-if and v-for on the same element at the same time?

When Vue processes instructions, the priority of v-for is higher than that of v-if. Therefore, this template:

<ul>
  <li v-for="item in list" v-if="item.isActive" :key="item.id">
    {{item.name}}
  </li>
</ul>

The following calculations will be performed:

this.list.map(function(item) {
  if (item.isActive) {
    return item.name
  }
})

Every time we re render, we have to traverse the whole list. Even if there are few item s with isActive as true, it will bring a great waste of performance. Therefore, the two cannot be used on the same element at the same time

2.2 solutions for V-IF and v-for

1. If you want to control the display and hiding of the whole list, you can move the v-if to the container element, for example:

<body>
  <div id="example">
    <ul v-if="listShow">
      <li v-for="item in activeItems" :key="item.id">{{item.name}}</li>
    </ul>
  </div>
</body>
<script>
  const vm = new Vue({
    el: "#example",
    data: {
      list: [
        { id: 1, name: "Monkey D Luffy", isActive: true },
        { id: 2, name: "Sauron", isActive: false },
        { id: 3, name: "Yamaji", isActive: true },
      ],
      listShow: false,
    }
  });
</script>

2. If you want to filter the items in the list, you can use the calculated attribute to return the filtered list, such as:

<body>
  <div id="example">
    <ul>
      <li v-for="item in activeItems" :key="item.id">{{item.name}}</li>
    </ul>
  </div>
</body>
<script>
  const vm = new Vue({
    el: "#example",
    data: {
      list: [
        { id: 1, name: "Monkey D Luffy", isActive: true },
        { id: 2, name: "Sauron", isActive: false },
        { id: 3, name: "Yamaji", isActive: true },
      ],
    },
    computed: {
      activeItems: function () {
        return this.list.filter((item) => item.isActive);
      },
    },
  });
</script>

3. What is the use of the key rendered in the list

When using v-for for list rendering, you must add a key attribute to the element, and the key must be a unique identifier

<ul>
	<li v-for="item in list" :key="item.id">{{item.name}}</li>
</ul>

We know that when updating elements, Vue does not directly operate the real DOM (rendering the real DOM is very expensive), but generates a new virtual DOM according to the new data, compares the differences between the old and new virtual DOMS, and updates the view by Dom operation according to the comparison results

When rendering a list, if there is a key attribute, because it is a unique identifier, there is no need for in-depth comparison if the keys are different when comparing two old and new nodes.

Why not use index as the key? Because the index is unstable and changeable, for example, deleting the first element of the list will change the index of the following element, resulting in the change of the key. At this time, when Vue compares the old and new nodes, it will make an in-depth comparison when it encounters a node with the same key. If it finds that the content of the node has changed, it will create a new real DOM to replace the original real dom. The operation that only needs to delete the first element in the real DOM will become creating and replacing all subsequent real DOMS, resulting in a great waste of performance

Topics: Front-end Vue