前言:
原因:因为 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
评论