v-if 和 v-for 哪个优先级更⾼?
结论
- ⽂档中明确指出永远不要把 v-if 和 v-for 同时⽤在同⼀个元素上,显然这是⼀个重要的注意事项。
- 在vue2中,v-for的优先级是高于v-if,把它们放在一起,会导致每一次遍历都会进行判断,哪怕我们只渲染列表中⼀⼩部分元素,也得在每次重渲染的时候遍历整个列表,这会⽐较浪费性能;另外需要注意的是在vue3中则完全相反,v-if的优先级⾼于v-for,所以v-if执⾏时,它调⽤的变量还不存在,就会导致异常报undefined。
- 通常有两种情况下导致我们这样做:
1.为了过滤列表中的项⽬ (⽐如 v-for="user in users" v-if="user.isActive")。此时定义⼀个计 算属性 (⽐如 activeUsers),让其返回过滤后的列表即可(⽐如 users.filter(u=>u.isActive))。
2.为了避免渲染本应该被隐藏的列表 (⽐如 v-for="user in users" v-if="shouldShowUsers")。此时把 v-if 移动⾄容器元素上 (⽐如 ul、ol)或者外⾯包⼀层template即可。 - 源码⾥⾯关于代码⽣成的部分,能够清晰的看到是先处理v-if还是v-for,顺序上vue2和vue3正好相反,因此 产⽣了⼀些症状的不同,但是不管怎样都是不能把它们写在⼀起的
参考:cn.vuejs.org/guide/essen…
案例:
为了过滤列表中的项⽬
<script setup lang="ts">
import { ref, computed } from 'vue'
const array = ref([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
// 展示过滤或排序后的结果
const computedArray = computed(() => {
return array.value.filter((item:number)=>item > 5)
})
const show = ref(false)
</script>
<template>
<div>
<ul>
<li v-for="item in computedArray" :key="item">{{ item }}</li>
</ul>
</div>
</template>
为了避免渲染本应该被隐藏的列表:
在外新包装一层 <template> 再在其上使用 v-for 可以解决这个问题 (这也更加明显易读)
<template v-for="todo in todos">
<li v-if="!todo.isComplete">{{ todo.name }} </li>
</template>