2022-09-16Vue00
请注意,本文编写于 582 天前,最后修改于 582 天前,其中某些信息可能已经过时。

v-if和v-for哪个优先级更高?

分析:

此题考查常识,文档中曾有详细说明v2|v3;也是一个很好的实践题目,项目中经常会遇到,能够看出面试者应用能力。

思路分析:总分总模式

  1. 先给出结论
  2. 为什么是这样的
  3. 它们能放一起吗
  4. 如果不能,那应该怎样
  5. 总结

回答范例:

  1. Vue 2 中,v-for 优先于 v-if 被解析;但在 Vue 3 中,则完全相反,v-if 的优先级高于 v-for

  2. 我曾经做过实验,把它们放在一起,输出的渲染函数中可以看出会先执行循环再判断条件

  3. 实践中也不应该把它们放一起,因为哪怕我们只渲染列表中一小部分元素,也得在每次重渲染的时候遍历整个列表。

  4. 通常有两种情况下导致我们这样做:

    • 为了过滤列表中的项目 (比如 v-for="user in users" v-if="user.isActive")。此时定义一个计算属性 (比如 activeUsers),让其返回过滤后的列表即可。

    • 为了避免渲染本应该被隐藏的列表 (比如 v-for="user in users" v-if="shouldShowUsers")。此时把 v-if 移动至容器元素上 (比如 ulol)即可。

  5. 文档中明确指出永远不要把 v-ifv-for 同时用在同一个元素上,显然这是一个重要的注意事项。

  6. 看过源码里面关于代码生成的部分,

知其所以然:

Vue 2 中做个测试, 两者同级时,渲染函数如下:

ƒ anonymous(
) {
with(this){return _c('div',{attrs:{"id":"app"}},_l((items),function(item){return (item.isActive)?_c('div',{key:item.id},[_v("\n      "+_s(item.name)+"\n    ")]):_e()}),0)}
}

Vue 3 中做个测试, 两者同级时,渲染函数如下:

(function anonymous(
) {
const _Vue = Vue

return function render(_ctx, _cache) {
  with (_ctx) {
    const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, toDisplayString: _toDisplayString, createCommentVNode: _createCommentVNode } = _Vue

    return shouldShowUsers
      ? (_openBlock(true), _createElementBlock(_Fragment, { key: 0 }, _renderList(items, (item) => {
          return (_openBlock(), _createElementBlock("div", { key: item.id }, _toDisplayString(item.name), 1 /* TEXT */))
        }), 128 /* KEYED_FRAGMENT */))
      : _createCommentVNode("v-if", true)
  }
}
})

源码中找答案: Vue 2compiler/codegen/index.js Vue 3compiler-core/src/codegen.ts

本文作者:毛超颖

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!