v-for和v-if优先级

544 阅读1分钟

v-for和v-if优先级

- Vue3 模板编译器

  • v-for、v-if同级

<div v-if="isShow" v-for="item in items" :key="item">{{item}}</div>
export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_ctx.isShow)
    ? (_openBlock(true), _createBlock(_Fragment, { key: 0 }, _renderList(_ctx.items, (item) => {
        return (_openBlock(), _createBlock("div", { key: item }, _toDisplayString(item), 1 /* TEXT */))
      }), 128 /* KEYED_FRAGMENT */))
    : _createCommentVNode("v-if", true)
  • v-if外、v-for内

<div v-if="isShow">
  <div v-for="item in items" :key="item">{{item}}</div>
</div>
export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_ctx.isShow)
    ? (_openBlock(), _createBlock("div", { key: 0 }, [
        (_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.items, (item) => {
          return (_openBlock(), _createBlock("div", { key: item }, _toDisplayString(item), 1 /* TEXT */))
        }), 128 /* KEYED_FRAGMENT */))
      ]))
    : _createCommentVNode("v-if", true)
}

- Vue2 模板编译器

  • v-for、v-if同级

 <div><div v-if="isShow" v-for="item in items" :key="item">{{item}}</div></div>
 with(this) {
     return _c('div', _l((items), function (item) {
         return (isShow) ? _c('div', {
             key: item
         }, [_v(_s(item))]) : _e()
     }), 0)
 }
  • v-if外、v-for内

<div v-if="isShow"><div v-for="item in items" :key="item">{{item}}</div></div>
with(this) {
    return (isShow) ? _c('div', _l((items), function (item) {
      return _c('div', {
        key: item
      }, [_v(_s(item))])
    }), 0) : _e()
  }
  • 源码 src\compiler\codegen\index.js L65

else if (el.for && !el.forProcessed) {
    return genFor(el, state)
} else if (el.if && !el.ifProcessed) {
    return genIf(el, state)

- 总结

  • vue2中v-for的优先级大于v-if,vue3中v-if优先级大于v-for

  • v-for优先级更高时,遍历时判断是否渲染,会造成不必要的操作

  • 可以在外面加上template标签写入v-if或者v-for逻辑