v-for 和 v-if 为什么不共存?
vue2
<div id="app">
<div v-for="item in [1, 2]" v-if="item !== 2"></div>
</div>
想要获取答案,可以打开这个网站:https://v2.template-explorer.vuejs.org/
这是一个解析Vue2
代码的网站,能把Vue
代码解析成最终的产物代码
其实重要的部分在这里
可以看到在Vue2
中,会先循环,然后在循环中去判断,判断为真则正常渲染,判断为假则执行_e
函数,_e
函数就是注释的意思,就是把判断为假的节点注释掉,也就是:
- 先走
v-for
循环 3 次 - 在循环体中走
v-if
判断 - 判断
item !== 2
则正常渲染,item === 2
则把这个节点注释掉
所以最终选出来 1、3 两个节点大家能理解为什么Vue2
会警告你了吗?
因为其实我们只需要渲染2个节点,但是最终还是循环了3次,造成了性能浪费,也就是 v-for 优先级高于 v-if,共存时会造成性能浪费
vue3
但是在Vue3
中,v-for
和v-if
却是可以共存的,为什么呢?我们还是拿最简单的代码来分析
<template>
<div v-for="item in [1, 2, 3]" v-if="item 1==2"></div>
</template>
我们可以到这个网站:https://play.vuejs.org/,看到解析后的产物
重要部分在这里
可以看到,跟Vue2
不同的是,Vue3
中是先走判断,然后再走循环的,也就是:
- 先走
v-if
判断 - 如果
item !== 2
,就去走循环也就是v-for
- 如果
item == 2
,就执行createCommandVNode
,创建一个注释节点
也就是在Vue3
中,v-if
优先级是高于v-for
的,真正循环的只有1、3这两个节点,这提高了性能
但是我们会看到,代码会报错:** item 找不到**?
这是因为在v-for
和v-if
共存的时候,Vue3
会在底层帮我们转换成
<template>
<template v-if="item !==2">
<div v-for="item in [1, 2, 3]"></div>
</template>
</template>
不信我们可以看看转换后的产物,跟刚刚是一模一样的!!!
item
是在外层的,所以报错说item
找不到,大家都知道为啥了吧?在外层怎么能获取到item
呢?
总结
总结就是不要让v-if
和v-for
共存在同一个标签中,遇到这种情况需要使用computed
去计算,然后再去渲染
<div v-for="item in list" :key="item"></div>
<script setup lang="ts">
import { computed } from 'vue'
const list = computed(() => [1, 2, 3].filter(item => item !== 2))
</script>
本文由mdnice多平台发布