云驹博客

路漫漫其修远兮,吾将上下而求索。

0%

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

v-if 和 v-for 的优先级

v-for 的优先级高于 v-if

1
<div v-if="flag" v-for="item in list"></div>

编译后生成的渲染函数:

1
2
3
ƒ anonymous() {
with(this){return _c('div',{attrs:{"id":"app"}},_l((list),function(item){return (flag)?_c('div',[_v(_s(item))]):_e()}),0)}
}

_l((list),function(item){return (flag)?_c('div',[_v(_s(item))]):_e()})从这段代码中可以清楚的看到先处理的list,其次在回调函数中处理的flag,因此可以推断出是先处理的v-for再处理的v-if

详见源码:Github Vue 源码 src/compiler/codegen/index.js

在解释器 genElement 方法中也可以清晰看到 v-for 优先于 v-if 执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
export function genElement(el: ASTElement, state: CodegenState): string {
if (el.parent) {
el.pre = el.pre || el.parent.pre;
}

if (el.staticRoot && !el.staticProcessed) {
return genStatic(el, state);
} else if (el.once && !el.onceProcessed) {
return genOnce(el, state);
} else if (el.for && !el.forProcessed) {
return genFor(el, state);
} else if (el.if && !el.ifProcessed) {
return genIf(el, state);
} else if (el.tag === "template" && !el.slotTarget && !state.pre) {
return genChildren(el, state) || "void 0";
} else if (el.tag === "slot") {
return genSlot(el, state);
} else {
// component or element
let code;
if (el.component) {
code = genComponent(el.component, el, state);
} else {
let data;
if (!el.plain || (el.pre && state.maybeComponent(el))) {
data = genData(el, state);
}

const children = el.inlineTemplate ? null : genChildren(el, state, true);
code = `_c('${el.tag}'${
data ? `,${data}` : "" // data
}${
children ? `,${children}` : "" // children
})`;
}
// module transforms
for (let i = 0; i < state.transforms.length; i++) {
code = state.transforms[i](el, code);
}
return code;
}
}

结论:v-for 的优先级高于 v-if

如有v-if要优先于v-for执行的情况,可以这样写:

1
2
3
<template v-if="flag">
<div v-for="item in list"></div>
</template>