前言:
原因:因为 v-for 优先级比 v-if 的优先级高,所以如果嵌套使用的话,每次 v-for 都会执行一次 v-if,而 v-if 是通过创建和销毁 dom 元素来控制元素的显示与隐藏,所以就会不停的去创建和销毁元素,造成页面卡顿,性能下降,所以 vue 官方不推荐这样使用。
为什么说 v-for 优先级比 v-if 的优先级高?
v-if 与 v-for 都是 vue 模板系统中的指令
在 vue 模板编译的时候,会将指令系统转化成可执行的 render 函数
示例
1、编写一个 p 标签,同时使用 v-if 与 v-for
<div id="app">
<p v-if="show" v-for="item in arr">
{{ item.title }}
</p>
</div>
复制代码
2、创建 vue 实例,存放 show 与 arr 数据
const app = new Vue({
el: "#app",
data() {
return {
arr: [
{ title: "damo" },
{ title: "damo2" }]
}
},
computed: {
show() {
return this.arr && this.items.length > 0
}
}
})
复制代码
3、模板指令的代码都会生成在 render 函数中,通过 app.$options.render 就能得到渲染函数
ƒ anonymous() {
with (this) { return
_c('div', { attrs: { "id": "app" } },
_l((arr), function (item)
{ return (show) ? _c('p', [_v("\n" + _s(item.title) + "\n")]) : _e() }), 0) }
}
复制代码
_l 是 vue 的列表渲染函数,函数内部都会进行一次 if 判断
得到结论:v-for 优先级是比 v-if 高
再看一个示例:可直观的感受到,v-if 和 v-for 一起使用所带来的性能影响
<template>
<div class="hello">
<div v-for="(item,index) in list" v-if="index === 9" :key="item" ></div>
</div>
</template>
<script>
export default {
name: "IndexCom",
data(){
return {
list:[1,2,3,4,5,6,7,8,9,10] //需要遍历的数据
}
}
};
</script>
复制代码
上面这组代码和下面这组是等价的
<template>
<div class="hello">
<div v-if="0 === 10"></div> //第1次判断
<div v-if="1 === 10"></div> //第2次判断
<div v-if="2 === 10"></div> //第3次判断
<div v-if="3 === 10"></div> //第4次判断
<div v-if="4 === 10"></div> //第5次判断
<div v-if="5 === 10"></div> //第6次判断
<div v-if="6 === 10"></div> //第7次判断
<div v-if="7 === 10"></div> //第8次判断
<div v-if="8 === 10"></div> //第9次判断
<div v-if="9 === 10"></div> //第10次判断
</div>
</template>
<script>
export default {
name: "IndexCom",
data() {
return {
list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
};
},
};
</script>
复制代码
优化方案【避免一起使用的】
1、在 v-if 不依赖 v-for 的前提下,我们可以将 v-if 写在 v-for 的外层,这样就可以让 v-if 判断优先
2、当 v-if 的判断条件依赖于 v-for 的某个值时(item,index),我们可以提前过滤数组
<template>
<div class="hello">
<!-- 2. 然后这里去循环已经被过滤的属性 -->
<div v-for="(item) in ListArr" :key="item" ></div>
</div>
</template>
<script>
export default {
name: "IndexCom",
data(){
return {
list:[1,2,3,4,5,6,7,8,9,10]
}
},
computed:{
//1. 在computed里先做好判断,这里过滤的成本远比v-if的成本低
ListArr(){
return this.list.filter((_,index) => index === 1)
}
}
};
</script>
复制代码
注:vue3 更新了 v-if 和 v-for 的优先级,使 v-if 的优先级高于 v-for
评论