<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div v-for="item in listdata" v-if="isShow(item)">姓名:{{item.name}},年龄:{{item.age}}</div>
</div>
<script type="text/javascript">
// 创建实例
var app = new Vue({
el: '#app',
data() {
return {
listdata: [{
name: '张三',
age: 17
},
{
name: '李四',
age: 18
}, {
name: '王五',
age: 19
}
],
visible: true
}
},
computed: {
},
methods: {
isShow(item) {
try {
console.log("判断一次=", JSON.stringify(item));
} catch (e) {
console.log("出错", e);
}
return this.visible;
}
}
});
console.log("渲染函数", app.$options.render);
</script>
</body>
</html>
运行结果:
通过观察运行结果发现,isShow方法执行了3次,说明v-for优先级高于v-if。
源码:compiler/codegen/index.js
render函数:
(function anonymous() {
with(this) {
return _c('div', {
attrs: {
"id": "app"
}
}, _l((listdata), function(item) {
return (isShow()) ? _c('div', [_v("姓名:" + _s(item.name) + ",年龄:" + _s(item.age))]) : _e()
}), 0)
}
})
代码优化:
<template v-if="isShow()">
<div v-for="item in listdata">姓名:{{item.name}},年龄:{{item.age}}</div>
</template>
render函数:
(function anonymous() {
with(this) {
return _c('div', {
attrs: {
"id": "app"
}
}, [(isShow()) ? _l((listdata), function(item) {
return _c('div', [_v("姓名:" + _s(item.name) + ",年龄:" + _s(item.age))])
}) : _e()], 2)
}
})
条件在循环内部(eg:只显示年龄大于17岁):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div v-for="item in verifyList">姓名:{{item.name}},年龄:{{item.age}}</div>
</div>
<script type="text/javascript">
// 创建实例
var app = new Vue({
el: '#app',
data() {
return {
listdata: [{
name: '张三',
age: 17
},
{
name: '李四',
age: 18
}, {
name: '王五',
age: 19
}
],
visible: true
}
},
computed: {
verifyList() {
let showlist = [];
//筛选出年龄大于17岁
for (var i = 0; i < this.listdata.length; i++) {
if (this.listdata[i].age > 17) {
showlist.push(this.listdata[i]);
}
}
return showlist;
}
},
methods: {
isShow(item) {
try {
console.log("判断一次=", JSON.stringify(item));
} catch (e) {
console.log("出错", e);
}
return this.visible;
}
}
});
console.log("渲染函数", app.$options.render);
</script>
</body>
</html>
结论:
1. v-for优先级高于v-if;(结论)
2. 如果同时出现,每次渲染都会先执行循环再判断条件,无论如何循环都不可避免,浪费性能;(缺点)
3. 要避免出现这种情况,则在外层嵌套template,在这一层进行v-if判断,然后在内部进行v-for循环;(优化)
4. 如果条件出现在循环内部,可通过计算属性提前过滤掉那些不需要显示的项。(优化)