关于v-if和v-for的执行顺序

562 阅读1分钟

先说结论:vue2中v-for优先执行,vue3中v-if优先执行

Vue2版本下

  • 如果同时使用v-for和v-if,代码会报错

示例代码

<div v-if="false" v-for="item in list" :key="item">{{ item }}</div>

运行结果:

查看vue2源码可以知道:v-for是在v-if之前执行

  • 也就说先把节点遍历渲染后,在重复的使用v-if去判断是否挂载,这样会造成大量的性能浪费。
  • 官方推荐将v-if放在最外层执行
...
    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 {
 ...

Vue3版本下

  • 在vue3中如果同时使用v-if和v-for不会报错,页面正常显示
  • 但eslint会有警告

那他们的执行顺序是怎样的呢?

  • 我们尝试在v-if中访问v-for出来的变量
<div v-if="item" v-for="item in list" :key="item">{{ item }}</div>
  • 执行后,发现页面什么也不展示,猜测是因为item是undefined,然后更改一下代码
<div v-if="item === undefined" v-for="item in list" :key="item">{{ item }}</div>
  • 这样后,页面就显示出来了

推断:

  • 由此可以推断出,vue3版本中,v-if先执行,因此他无法访问v-for中的变量
  • 虽然vue3下同时使用v-if和v-for不会报错,但还是不推荐这样的用法