做个检验如下 vue2示例
<!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/vue2.js"></script>
<script>
// 创建实例 vue2
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>
两者同级时,烘托函数如下:
(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
是对children的循环,判别条件是isFolder
可见他是包含在循环里的所以v-for是比v-if的优先级高,其实缺点也是很显着的放在一起每次循环都要去判别是糟蹋功用的,我们看看vue2的源码
源码v-for的优先级也是高于v-if的
_l包含了
isFolder
的条件判别
(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)}
})
isFolder
条件用template包裹后,条件在前面而循环在后面
同理我们看看vue3的
<!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/vue3.js"></script>
<script>
// vue3
const app = Vue.createApp({
template: "",
data() {
return {
children: [{ title: "foo" }, { title: "bar" }],
};
},
computed: {
isFolder() {
return this.children && this.children.length > 0;
},
},
});
app.mount("#demo");
console.log(app._component.render);
</script>
</body>
</html>
两者同级时,烘托函数如下:
(function anonymous() {
const _Vue = Vue
const { createElementVNode: _createElementVNode, createCommentVNode: _createCommentVNode } = _Vue
const _hoisted_1 = /*#__PURE__*/_createElementVNode("h1", null, "v-for和v-if谁的优先级高?应该怎样正确运用避免功用问题?", -1 /* HOISTED */)
return function render(_ctx, _cache) {
with (_ctx) {
const { createElementVNode: _createElementVNode, renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, toDisplayString: _toDisplayString, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), _createElementBlock(_Fragment, null, [
_hoisted_1,
isFolder
? (_openBlock(true), _createElementBlock(_Fragment, { key: 0 }, _renderList(children, (child) => {
return (_openBlock(), _createElementBlock("p", null, _toDisplayString(child.title), 1 /* TEXT */))
}), 256 /* UNKEYED_FRAGMENT */))
: _createCommentVNode("v-if", true),
_createCommentVNode(" <template v-if="isFolder">n <p v-for="child in children">{{child.title}}</p>n </template> ")
], 64 /* STABLE_FRAGMENT */))
}
}
})
显着这次的烘托函数isFolder
放在了循环前面所以这次的v-if是优先于v-for
结论:
- vue2
- 显着v-for优先于v-if被解析(把你是怎样知道的奉告面试官)
- 假如一起出现,每次烘托都会先履行循环再判别条件,无论怎样循环都不可避免,糟蹋了功用
- 要避免出现这种情况,则在外层嵌套template,在这一层进行v-if判别,然后在内部进行v-for循环
- 假如条件出现在循环内部,可通过核算特点提早过滤掉那些不需要闪现的项
- vue3
- 显着v-if优先于for被解析(把你是怎样知道的奉告面试官)
这儿弥补下_l
和renderList
关系
从vue3源码找到
renderList
是针对不同类型进行遍历再将其回来
如有大佬的主张,可以点评