v-if和v-for——Vue性能优化 | 青训营
Vue性能优化——v-if和v-for
在代码中,将v-for
与v-if
同时使用,在vue2和vue3中有不同的结果
v-if和v-for不能同时出现
以下为简单代码示例,包括数据data和html代码
data() {
return {
arr: [
{ name: 'Mary', isShow: true },
{ name: 'Kate', isShow: false },
{ name: 'John', isShow: true },
{ name: 'Tom', isShow: false },
{ name: 'Jerry', isShow: true }
],
}
}
<div id="app">
<template>
<ul>
<li v-for="(item, index) in arr" :key="index" v-if="item.isShow">{{ index }}: {{ item.name }}</li>
</ul>
</template>
</div>
- 在vue2中,可以正常运行,得到如下结果,0,2,4的顺序也可以说明
v-for
先运行:
- 而在vue3中,则会出现错误提示:
-
这是由于在vue2和vue3中
v-if
与v-for
的优先级不同:- vue2中,
v-for
比v-if
的优先级更高,v-if
的条件可以访问到v-for
作用域内定义的变量别名 - vue3中,
v-if
比v-for
的优先级更高,v-if
的条件将无法访问到v-for
作用域内定义的变量别名
- vue2中,
大家可以参考官方文档:列表渲染 | Vue.js (vuejs.org)
解决方案
法一:
- 当
v-if
不依赖v-for时
,我们可以将v-if
写在v-for
的外层,这样就可以让v-if
判断优先
当然,这种方法不适合我们的例子
如果是要通过
v-if
控制整个ul列表的出现,则可以通过在代码进行以下修改来实现,当然不要忘记声明ifShowList
<template v-if="ifShowList"> <ul> ... </ul> </template>
当然,
<template></template>
不是必须的,如果用其他标签也是可以的
法二:
- 当
v-if
的判断条件依赖于v-for
的某个值时(item,index)
,也就是我们例子的情况,可以通过计算属性进行过滤的方法,直接遍历过滤后的列表,像这样在计算属性中过滤的成本远比v-if
的成本低
computed:{
newArr(){
return this.arr.filter(item => item.isShow)
}
}
<div id="app">
<ul>
<li v-for="(item, index) in newArr" :key="index">{{ index }}: {{ item.name }}</li>
</ul>
</div>
- 最后的执行结果如下:
总结
v-if
和v-for
不能一起使用的原因是他们的优先级不同,在vue2中v-for
的优先级比v-if
的优先级高,一起使用会造成性能浪费- 解决方案:把
v-if
放在v-for
的外层;把需要v-for
的属性先从计算属性中过滤一次
虽然在vue3中
v-if
优先级比v-for
的优先级高,但还是建议不要在一起使用