A,

The V-if directive is used to conditionally render a piece of content. This content will only be rendered if the expression of the directive returns true

The V-for directive renders a list based on an array. The V-for directive requires a special syntax of the form item in Items, where items are the source data array or object and item is the alias of the array element being iterated over

In v-for, it is recommended to set the key value and ensure that each key value is unique, which facilitates the optimization of the DIff algorithm

Both in terms of usage

<Demo v-if="isShow" />

<li v-for="item in items" :key="item.id">
    {{ item.label }}
</li>
Copy the code

Second, priority

V-if and V-for are instructions in the VUE template system

When the Vue template is compiled, the instruction system is converted into an executable render function

The sample

Write a p tag that uses both V-if and V-for

<div id="app">
    <p v-if="isShow" v-for="item in list">
        {{ item.name }}
    </p>
</div>
Copy the code

Create a vue instance to store isShow and Items data

const app = new Vue({
  el: "#app",
  data() {
    return {
      list: [
        { name: "Tom" },
        { name: "Jack" }]
    }
  },
  computed: {
    isShow() {
      return this.list && this.list.length > 0
    }
  }
})
Copy the code

The template command code is generated in the render function, which is available via app.$options.render

ƒ anonymous() {with (this) {return _c('div', {attrs: {"id": "app" } }, _l((list), function (item) { return (isShow) ? _c('p', [_v("\n" + _s(item.name) + "\n")]) : _e() }), 0) } }Copy the code

_l is vue’s list rendering function, and the function is always evaluated internally by an if

The preliminary conclusion is that v-for has a higher priority than V-IF

Then put v-for and V-IF on different labels

<div id="app">
    <template v-if="isShow">
        <p v-for="item in list">{{item.name}}</p>
    </template>
</div>
Copy the code

Output the render function again

ƒ anonymous () {with (this) {return _c (' div '{attrs: {" id ":" app "}}, [(isShow)? [_v (" \ n "), _l((list),function(item){return _c('p',[_v(_s(item.name))])})]:_e()],2)} }Copy the code

In this case, we can see that v-for and V-if are used for different tags to judge first and then render the list

Let’s look at the vue source code again

Source location: vue/dev/SRC/compiler/codegen/index. Js

export function genElement (el: ASTElement, state: CodegenState): string { if (el.parent) { el.pre = el.pre || el.parent.pre } if (el.staticRoot && ! el.staticProcessed) { return genStatic(el, state) } else if (el.once && ! el.onceProcessed) { return genOnce(el, state) } else if (el.for && ! el.forProcessed) { return genFor(el, state) } else if (el.if && ! el.ifProcessed) { return genIf(el, state) } else if (el.tag === 'template' && ! el.slotTarget && ! state.pre) { return genChildren(el, state) || 'void 0' } else if (el.tag === 'slot') { return genSlot(el, state) } else { }Copy the code
}
Copy the code

In the if judgment, v-for is judged before V-if

Final conclusion: V-for has a higher priority than V-IF

Three, notes

  1. Never give upv-if 和 v-forUse of the same element at the same time, resulting in a performance waste (each render is loiterable and then conditional)
  2. If this is avoided, it is nested in the outer layertemplatePage rendering is not generateddomNode), the v-IF judgment is performed at this layer, and then the V-for loop is performed internally
<template v-if="isShow">
    <p v-for="item in list">
</template>
Copy the code
  1. If the condition occurs inside the loop, you can evaluate the attributecomputedFilter out items that don’t need to be displayed in advance
computed: {
    items: function() {
      return this.list.filter(function (item) {
        return item.isShow
      })
    }
}
Copy the code