vue中v-for 和 v-if 的优先级

221 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

v-for 和 v-if 的优先级

v-for的优先级要比v-if高,v-for优先于v-if被解析。

vue源码参考:dist/vue.js

// 处理element,分别处理static静态节点、v-once、v-for、v-if、template、slot以及组件或元素
function genElement(el, state) {
    if (el.parent) {
        el.pre = el.pre || el.parent.pre;
    }
    // 对各种类型做处理
    if (el.staticRoot && !el.staticProcessed) { // 处理static静态节点
        return genStatic(el, state)
    } else if (el.once && !el.onceProcessed) { // 处理v-once
        return genOnce(el, state)
    } else if (el.for && !el.forProcessed) { // 处理v-for
        return genFor(el, state)
    } else if (el.if && !el.ifProcessed) { // 处理v-if
        return genIf(el, state)
    } else if (el.tag === 'template' && !el.slotTarget && !state.pre) { // 处理template
        return genChildren(el, state) || 'void 0'
    } else if (el.tag === 'slot') {  // 处理slot
        return genSlot(el, state)
    } else {
        // component or element
        // 处理组件或元素
        var code;
        if (el.component) {
            code = genComponent(el.component, el, state);
        } else {
            var data;
            if (!el.plain || (el.pre && state.maybeComponent(el))) {
                data = genData$2(el, state);
            }
            var children = el.inlineTemplate ? null : genChildren(el, state, true);
            code = "_c('" + (el.tag) + "'" + (data ? ("," + data) : '') + (children ? ("," + children) : '') + ")";
        }
        // module transforms
        for (var i = 0; i < state.transforms.length; i++) {
            code = state.transforms[i](el, code);
        }
        return code
    }
}

如果二者同时出现在同级,每次渲染都会先执行循环,再判断条件,由此可见对性能损耗比较大。

性能优化:可以在外层添加判断条件,在内层执行循环。判断条件只执行一次,且v-if 为false时,不执行v-for。

<div id="demo">
    <!--用法一,不推荐,先走循环浪费性能-->
    <!-- <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>