源码中找答案compiler/codegen/index.js
<p v-for="item in items" v-if="condition">
先看一下小demo
<!DOCTYPE html>
<html>
<head>
<title>Vue事件处理</title>
</head>
<body>
<div id="demo">
<h1>v-for和v-if谁的优先级高?应该如何正确使用避免性能问题?</h1>
<p v-for="child in children" v-if="isFolder">{{child.title}}</p>
<template v-if="isFolder">
<p v-for="child in children">{{child.title}}</p>
</template>
</div>
<script src="../../dist/vue.js"></script>
<script>
// 创建实例
const app = new Vue({
el: '#demo',
data() {
return {
children: [
{ title: 'foo' },
{ title: 'bar' },
]
}
},
computed: {
isFolder() {
return this.children && this.children.length > 0
}
},
});
console.log(app.$options.render);
</script>
</body>
</html>
两者同级时,渲染函数如下:(包含了isFolder的条件判断)
function anonymous() {
with(this){return _c('div',{attrs:{"id":"demo"}},[_c('h1',[_v("v-for和v-if谁的优先级高?应该如何正确使用避免性能问题?")]),_v(" "),_l((children),function(child){return (isFolder)?_c('p',[_v(_s(child.title))]):_e()})],2)}}
两者不同级时,渲染函数如下:(先判断了条件再看是
否执行_l)
(function anonymous(
) {with(this){return _c('div',{attrs:{"id":"demo"}},[_c('h1',[_v("v-for和v-if谁的优先级高?应该如何正确使用避免性能问题?")]),_v(" "),(isFolder)?_l((children),function(child){return _c('p',
[_v(_s(child.title))])}):_e()],2)}
})
结论:
Vue组件可能存在多个实例,如果使用对象形式定义data,则会导致它们共用一个data对象,那么状态 变更将会影响所有组件实例,这是不合理的;采用函数形式定义,在initData时会将其作为工厂函数返 回全新data对象,有效规避多实例之间状态污染问题。而在Vue根实例创建过程中则不存在该限制,也 是因为根实例只能有一个,不需要担心这种情况。