Advertisement

Vue篇(006)-为什么避免 v-if 和 v-for 用在一起

阅读量:

参考答案:

在vue2.x版本中,v-for的优先顺序高于v-if,而在vue3.x版本中则相反.因此,在一个元素上同时使用v-if和v-for时,在2.x版本中,v-for会先起作用,从而导致性能上的不必要的消耗.到了3.x版本中,v-if总是先于v-for生效,这使得在某些情况下无法正确获取到用于处理的数据.

解析:

一般我们在两种常见的情况下会倾向于这样做:

为了筛选列表中的项(如通过 v-for="user in users" 和 v-if="user.isActive" 实现)。在此情况下,请将 users 替换为一个计算属性(如 activeUsers),以便获取过滤后的结果。

为了解决在使用v-for和v-if时出现渲染问题,在不显示用户数据的情况下仍然希望展示用户列表的问题,请将v-if绑定到容器元素上(例如ul、ol)。

当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,所以这个模板:

复制代码
    <ul>
      <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
      >
    {{ user.name }}
      </li>
    </ul>

将会经过如下运算:

复制代码
    this.users.map(function (user) {
      if (user.isActive) {
    return user.name
      }
    })

由此可见,在即使我们仅生成少量用户的元素时,在每次重新渲染时都需要遍历全部列表(无论活跃用户的状况如何)。

通过将其更换为在如下的一个计算属性上遍历:

复制代码
    computed: {
      activeUsers: function () {
    return this.users.filter(function (user) {
      return user.isActive
    })
      }
    }
复制代码
    <ul>
      <li
    v-for="user in activeUsers"
    :key="user.id"
      >
    {{ user.name }}
      </li>
    </ul>

我们将会获得如下好处:

  • 过滤后的列表仅在 users 数组发生变化时才会重新计算效率更高。
  • 引入 v-for=‘user in activeUsers’ 后渲染流程仅处理活跃用户。
  • 将渲染层与业务逻辑分离以提升代码可维护性和扩展能力。

为了获得同样的好处,我们也可以把:

复制代码
    <ul>
      <li
    v-for="user in users"
    v-if="shouldShowUsers"
    :key="user.id"
      >
    {{ user.name }}
      </li>
    </ul>

更新为:

复制代码
    <ul v-if="shouldShowUsers">
      <li
    v-for="user in users"
    :key="user.id"
      >
    {{ user.name }}
      </li>
    </ul>

通过移动 v-if 到容器元素, 我们不再逐个对列表中的每个用户进行 shouldShowUsers 检查. 同时仅需进行一次判断, 并无需在此时执行 v-for 循环操作.

反例:

复制代码
    <ul>
      <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
      >
    {{ user.name }}
      </li>
    </ul>
    
    <ul>
      <li
    v-for="user in users"
    v-if="shouldShowUsers"
    :key="user.id"
      >
    {{ user.name }}
      </li>
    </ul>

好例子

复制代码
    <ul>
      <li
    v-for="user in activeUsers"
    :key="user.id"
      >
    {{ user.name }}
      </li>
    </ul>
    
    <ul v-if="shouldShowUsers">
      <li
    v-for="user in users"
    :key="user.id"
      >
    {{ user.name }}
      </li>
    </ul>

参与互动

全部评论 (0)

还没有任何评论哟~