0
点赞
收藏
分享

微信扫一扫

Vue--v-if和v-for不能同时使用--原因/解决方案/实例

Go_Viola 2022-01-17 阅读 115

原文网址:Vue--v-if和v-for不能同时使用--原因/解决方案/实例_IT利刃出鞘的博客-CSDN博客

简介

简介

本文介绍v-if和v-for不要同时使用的原因及解决方案。

官网

条件渲染 — Vue.js

风格指南 — Vue.js

原因与解决方案

说明

        当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。

        vue官方着重强调:永远不要把 v-if 和 v-for 同时用在同一个元素上。

v-if和v-for不能同时使用的原因

        v-for比v-if优先级高,每一次都需要遍历整个数组,造成不必要的计算,影响性能。即使100个list中只需要使用一个数据,也会循环整个数组。

解决方案

场景1:每项都有自己的状态

        例:v-for="user in users" v-if="user.isActive"。将 users 替换为一个计算属性 (比如 activeUsers),让其返回过滤后的列表。

场景2:有公共的状态

        例:v-for="user in users" v-if="shouldShowUsers"。将 v-if 移动至外部容器元素上 (比如 ul、ol)。

示例1:每项都有自己的状态

公共代码

路由(router/index.js)

import Vue from 'vue'
import Router from 'vue-router'
import Demo from "../views/Demo";

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/demo',
      name: 'Demo',
      component: Demo,
    }
  ],
})

反例

代码

Demo.vue

<template>
  <div class="hello">
    <ul>
      <li
          v-for="user in users"
          v-if="user.isActive"
          :key="user.userId"
      >
        {{user.userName}}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'Demo',
  data () {
    return {
      users: [
        {
          userId: 1,
          userName: 'Tony1',
          isActive: true
        },
        {
          userId: 2,
          userName: 'Tony2',
          isActive: false
        },
        {
          userId: 3,
          userName: 'Tony3',
          isActive: true
        }
      ]
    }
  },

}
</script>

<style scoped>

</style>

测试

访问:http://localhost:8080/#/demo

总结

当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,所以上述模板会进行如下运算:

this.users.map(function (user) {
  if (user.isActive) {
    return user.name
  }
})

  因此哪怕我们只渲染出一小部分用户的元素,也得在每次重渲染的时候遍历整个列表。

好例子

代码

Demo.vue

<template>
  <div class="hello">
    <ul>
      <li
          v-for="user in activeUsers"
          :key="user.userId"
      >
        {{user.userName}}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'Demo',
  data () {
    return {
      users: [
        {
          userId: 1,
          userName: 'Tony1',
          isActive: true
        },
        {
          userId: 2,
          userName: 'Tony2',
          isActive: false
        },
        {
          userId: 3,
          userName: 'Tony3',
          isActive: true
        }
      ]
    }
  },
  computed: {
    activeUsers() {
      return this.users.filter(function (user) {
        return user.isActive;
      })
    }
  }

}
</script>

<style scoped>

</style>

测试

访问:http://localhost:8080/#/demo

示例2:有公共的状态

公共代码

路由(router/index.js)

import Vue from 'vue'
import Router from 'vue-router'
import Demo from "../views/Demo";

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/demo',
      name: 'Demo',
      component: Demo,
    }
  ],
})

反例

代码

Demo.vue

<template>
  <div class="hello">
    <ul>
      <li
          v-for="user in users"
          v-if="userActive"
          :key="user.userId"
      >
        {{user.userName}}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'Demo',
  data () {
    return {
      userActive: true,
      users: [
        {
          userId: 1,
          userName: 'Tony1',
        },
        {
          userId: 2,
          userName: 'Tony2',
        },
        {
          userId: 3,
          userName: 'Tony3',
        }
      ]
    }
  },
}
</script>

<style scoped>

</style>

测试

访问:http://localhost:8080/#/demo

好例子

代码

Demo.vue

<template>
  <div class="hello">
    <ul v-if="userActive">
      <li
          v-for="user in users"
          :key="user.userId"
      >
        {{user.userName}}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'Demo',
  data () {
    return {
      userActive: true,
      users: [
        {
          userId: 1,
          userName: 'Tony1',
        },
        {
          userId: 2,
          userName: 'Tony2',
        },
        {
          userId: 3,
          userName: 'Tony3',
        }
      ]
    }
  },
}
</script>

<style scoped>

</style>

测试

访问:http://localhost:8080/#/demo

举报

相关推荐

0 条评论