v-if / v-else(-if)

827 阅读2分钟
<div v-if="status === 1">
	1
</div>
<div v-else-if="status === 2">
	2
</div>
<div v-else>
	3
</div>

0-指令从解析,到节点信息,再到渲染

1- 获取标签上的指令属性parseStartTag()

## v-if
element1 = {
	type:1,
    tag:'div',
    attrsList:[{name:'v-if',value:"status === 1"}],
    attrsMap:{'v-if':"status === 1"}
}
## v-else-if
element2 = {
	type:1,
    tag:'div',
    attrsList:[{name:'v-else-if',value:"status === 2"}],
    attrsMap:{'v-else-if':"status === 2"}
}
## v-else
element3 = {
	type:1,
    tag:'div',
    attrsList:[{name:'v-else',value:undefined}],
    attrsMap:{'v-else':undefined}
}

2- 解析指令属性(processIf、closeElement)

在processIf函数中会解析 v-if / v-else / v-else-if 标签属性
## v-if
element1 = {
	type:1,
    tag:'div',
    attrsList:[],                             //删除关于v-if的属性对象
    attrsMap:{'v-if':"status === 1"},
    if:"status === 1",                        //添加节点属性
    ifConditions:[
        {exp:"status === 1",block:element1},   //添加条件属性,及对应的节点(element也就是当前节点)
    ]
}
## v-else-if
element2 = {
	type:1,
    tag:'div',
    attrsList:[],                             //删除关于v-else-if的属性对象
    attrsMap:{'v-else-if':"status === 2"},
    elseif:"status === 2",                        //添加节点属性
}
## v-else
element3 = {
	type:1,
    tag:'div',
    attrsList:[],                             //删除关于v-else的属性对象
    attrsMap:{'v-else':undefined},
    else:true,                        //添加节点属性
}
/*********
最终只有v-if属性有ifConditions属性保存我们的v-if的表达式(exp)和对应的节点(element)。
因为我们的v-else(-if)属性会在关闭【含有v-else,v-else-if指令】的标签时,
将我们的节点放到v-if的标签中的ifConditions中。最终我们的element2和element3都会放到element1中
**/
element1 = {
	type:1,
    tag:'div',
    attrsList:[],                             
    attrsMap:{'v-if':"status === 1"},
    if:"status === 1",                       
    ifConditions:[
        {exp:"status === 1",block:element1}, 
        {exp:"status === 2",block:element2}, 
        {exp:undefined,block:element3}, 
    ]
}
注:- v-if 和 v-else(-if)中间不能有节点(type === 1) //会产生告警
   - v-if 和 v-else(-if)中间的text会被忽略。

3- 渲染函数的生成 genIf

对于有 if属性的节点element1,会运行genif属性返回对应条件的渲染函数(暂时不考虑v-if与v-once混用);
genIfConditions=[
        {exp:"status === 1",block:element1}, 
        {exp:"status === 2",block:element2}, 
        {exp:undefined,block:element3}, 
    ]
对于element1,会返回一个三元表达式:
(exp1 ? genElement(element1) : genIfConditions)

当满足第一个exp条件时,会使用对应的element1,当不满足的话,会判断下一个exp条件是否成立,
条件成立会使用对应的element2,对于v-else,我们的exp是undefined,会使用undefined 的element3.
v-else-if 没有对应exp时,解析结果和v-else相同。