v-if和v-for哪个优先级更高
- 实践中不应该把
v-for
和v-if
放一起 - 在
vue2
中,v-for
的优先级是高于v-if
,把它们放在一起,输出的渲染函数中可以看出会先执行循环再判断条件,哪怕我们只渲染列表中一小部分元素,也得在每次重渲染的时候遍历整个列表,这会比较浪费;另外需要注意的是在vue3
中则完全相反,v-if
的优先级高于v-for
,所以v-if
执行时,它调用的变量还不存在,就会导致异常 - 通常有两种情况下导致我们这样做:
- 为了过滤列表中的项目 (比如
v-for="user in users" v-if="user.isActive"
)。此时定义一个计算属性 (比如activeUsers
),让其返回过滤后的列表即可(比如users.filter(u=>u.isActive)
) - 为了避免渲染本应该被隐藏的列表 (比如
v-for="user in users" v-if="shouldShowUsers"
)。此时把v-if
移动至容器元素上 (比如ul
、ol
)或者外面包一层template
即可
- 为了过滤列表中的项目 (比如
- 文档中明确指出永远不要把
v-if
和v-for
同时用在同一个元素上,显然这是一个重要的注意事项 - 源码里面关于代码生成的部分,能够清晰的看到是先处理
v-if
还是v-for
,顺序上vue2
和vue3
正好相反,因此产生了一些症状的不同,但是不管怎样都是不能把它们写在一起的
vue2.x源码分析
在vue模板编译的时候,会将指令系统转化成可执行的
render
函数
编写一个p
标签,同时使用v-if
与 v-for
<div id="app">
<p v-if="isShow" v-for="item in items">
{
{ item.title }}
</p>
</div>
创建vue
实例,存放isShow
与items
数据
const app = new Vue({
el: "#app",
data() {
return {
items: [
{
title: "foo" },
{
title: "baz" }]
}
},
computed: {
isShow() {
return this.items && this.items.length > 0
}
}
})
模板指令的代码都会生成在render
函数中,通过app.$options.render
就能得到渲染函数
ƒ anonymous() {
with (this) {
return
_c('div', {
attrs: {
"id": "app" } },
_l((items), function (item)
{
return (isShow) ? _c('p', [_v("\n" + _s(item.title) + "\n")]) : _e() }), 0) }
}
_l
是vue
的列表渲染函数,函数内部都会进行一次if
判断- 初步得到结论:
v-for
优先级是比v-i
f高 - 再将
v-for
与v-if
置于不同标签
<div id="app">
<template v-if="isShow">
<p v-for="item in items">{
{item.title}}</p>
</template>
</div>
再输出下render
函数
ƒ anonymous() {
with(this){
return
_c('div',{
attrs:{
"id":"app"}},
[(isShow)