v-for和v-if是可以一起使用的,vue官网:当同时使用时,v-if
比 v-for
优先级更高。我们并不推荐在一元素上同时使用这两个指令。
官网例子:
<!--
这会抛出一个错误,因为属性 todo 此时
没有在该实例上定义
-->
<li v-for="todo in todos" v-if="!todo.is***plete">
{{ todo.name }}
</li>
在外新包装一层 <template>
再在其上使用 v-for
可以解决这个问题 (这也更加明显易读):
<template v-for="todo in todos">
<li v-if="!todo.is***plete">
{{ todo.name }}
</li>
</template>
白话来说 先执行v-for 进行创建了多个dom元素,这时再去使用v-if 销毁了很多无用创建出来的的元素,非常浪费性能。
举个例子
<ul>
<li v-for="item in list" v-if="item % 2 ==0"> {{ item }} </li>
</ul>
data () {
return {
list: [1, 2, 3, 4, 5, 6]
}
}
在上面例子中 123456渲染成每个li 标签 在使用v-if 把不满足条件的给销毁掉,如果在这之前把数据过滤出来是不是就解决啦?
解决方案 计算属性(***puted)
<ul>
<li v-for="item in newList" > {{ item }} </li>
</ul>
data () {
return {
list: [1, 2, 3, 4, 5, 6]
}
},
***puted: {
newList () {
return this.list.filter(item => item % 2 === 0)
}
}
既然计算属性可以解决,那什么时候使用官网中提到的template呢?
再来看这个例子
<ul>
<li v-for="item in newList" v-if="flag"> {{ item }} </li>
</ul>
data () {
return {
list: [1, 2, 3, 4, 5, 6],
flag: false // 判断是否隐藏
}
},
当flag为false就隐藏 所有li ,这时候就可以加一层template 进行使用v-if 当然给ul也是一样的。
<ul v-if="flag">
<li v-for="item in newList" > {{ item }} </li>
</ul>
<ul>
<template v-if="flag">
<li v-for="item in newList" > {{ item }} </li>
</template>
</ul>
总结:v-for和v-if可以同时使用,但不建议直接使用,如果想要使用有两种解决方案
一、在判断条件中不对循环数据作为v-if 的判断条件的时候可以加一层 template
二、如果要对循环数据作为v-if 的判断条件 可以提前把数据过滤出来 避免出现循环创建DOM元素后 销毁无用的DOM元素
强调:在vue2中 v-for和v-if同时使用时 v-for优先级大于v-if,vue3也是进行了优化 v-if 会比v-for先执行