v-if conditional instructions for rendering a content. This content will only return truthy value in the expression command when they were rendered.
v-else-if, as the name implies, serve as a v-if "else-if blocks" can be used continuously:
V-else may also be used to indicate instructions of v-if "else block":
Very good understanding of it, and if most of the language () .... else if () ... else statement is the same logic, for example:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> </head> <body> <script> Vue.config.productionTip=false; Vue.config.devtools=false; </script> <div id="app"> <p v-if="no<0">n小于0</p> <p v-else-if="no==0">no等于0</p> <p v-else>no大于0</p> </div> <script>var app = new Vue({el:'#app',data:{no:</}})2script> </body> </html>
Rendered as:
Note there are two points:
v-else和v-else-if
Must immediately with v-if
or v-else-if
after the element, while the source code will be mentioned when Why
Because v-if
a command, so it must be added to an element. But if you want to switch between multiple elements? At this time can be a <template>
element as invisible package elements,
Source code analysis
Vue interior will v-if, v-else, v-else-if parsing a called ternary operator , if there are a plurality of v-else, if the ternary operator then a nested ternary operator to examples in the example:
Template to parse parse < P V-IF = "NO <0" > n-less than 0 </ P > will be executed when the DOM element to processIf () function
function processIf (EL) { // section 9402 v-if command line parsing var exp = getAndRemoveAttr (EL, 'v-if'); // Get the expression, for example: "NO <0" IF (exp) { // If the attribute v-if present . el if = exp; // increase if properties addIfCondition (el, { // call addIfCondition () function to increase a ifConditions el attribute to an object, wherein exp denotes the current value of the v-if , block AST is the current reference object (while a v-else and v-else-if used) exp: exp, Block: EL }); } the else { // If there is no attribute v-if IF (! getAndRemoveAttr (EL, 'V-else') = null ) { // if present else command, else increase in a property el.else EL. else = to true ; } var ELSEIF = getAndRemoveAttr (EL, 'V IF--else '); // if v-elseif commands exist, add attributes elseif IF (elseif) { el.elseif = elseif; } } } function addIfCondition (EL, for condition Condition) { // increase line 9453 a ifConditions property, IF (! el.ifConditions) { el.ifConditions = []; //If the property does not exist ifConditions initialized to an empty array } el.ifConditions.push (condition); // parameter condition push this object come }
For v-if a node if and only increase ifConditions properties, for < P v-if = "NO <0" > n-less than 0 </ P > , the corresponding increase in AST objects following properties:
For v-else and v-else-if it is, and no new AST corresponding to the current object is added to the AST tree, but the AST corresponding to itself to add the object to the nearest ifConditions in v-if the code is as follows :
IF (currentParent &&! element.forbidden) { // first line 9223 if the current object is not the root object, and not the style and text / javascript type script tag IF (element.elseif || Element. the else ) { // if or elseif else there is an instruction (provided v-else instruction, or v-elseif) processIfConditions (element, currentParent); // is called processIfConditions () function } else IF (element.slotScope) { // scoped // If the element is a slot scope slot currentParent.plain = to false ; var name = element.slotTarget || ' "default"'; (currentParent.scopedSlots || (currentParent.scopedSlots = {})) [name] = Element; }else { currentParent.children.push(element); element.parent = currentParent; } }
AST will processIfConditions previous node, i.e. the node ifConditions AST v-if the added ast objects into the current, as follows:
function processIfConditions (EL, parent) { // line 9421 parses v-else, v-else- if instruction var PREV = findPrevElement (parent.children); // call findPrevElement objects before obtaining EL AST (AST only to find common elements ) IF . (prev prev && IF ) { // If prev is present, and v-if it contains instructions addIfCondition (prev, { // the call addIfCondition ifConditions prev added to a statement exp: el.elseif, Block: EL } ); } the else { The warn $ 2 ( ? "V-" + (el.elseif ( 'the else-IF = "' + el.elseif + '"'): 'the else') + " " + "Element Used ON <" + (el.tag) + "> the without the Corresponding V-IF." ); } } function findPrevElement (children) { // line 9436 to find a text before children objects AST var I = children.length ; the while (i--) { // iterate children, from the start of IF (Children [I] .Type ===. 1) { // If the node is a common return Children [I] // directly returns the element } the else { IF ( "Development"! == 'Production' && Children [I] .text! == '') { //Development mode, if the node is not an ordinary node, the error The warn $ 2 ( "text \" "+ (Children [I] .text.trim ()) +" \ "BETWEEN V-V and the else-IF (the -if)" + "Will BE ignored." ); } children.pop (); } } }
After the implementation of the entire AST object tree are as follows:
Generate performed next generation rendre function if there is always found on the implementation attribute genIf () function:
function genIf ( // line 10205 // v-if rendering instruction EL, State, altGen, altEmpty ) { el.ifProcessed = to true ; // Avoid avoid recursion // recursive return genIfConditions (el.ifConditions.slice (), State , altGen, altEmpty) // call the function genIfConditions } function genIfConditions ( // first row pieced 10215 if expression conditions: for example: [{exp: "OK", Block: {...}}] Conditions, State, altGen, altEmpty ) { IF (! conditions.length) { // If the conditions do not exist return altEmpty || '_E ()' // directly returns altEmpty } var for condition Condition conditions.shift = (); // get content, such as: {exp: "no <0 ", block: { }} ... IF (condition.exp) { // put together ternary operator return ( "(" + (condition.exp) + + (genTernaryExp (condition.block)) + ")?" ":" + (genIfConditions ( Conditions, State, altGen, altEmpty))) } the else { return ( "" + (genTernaryExp (condition.block))) } // V-V IF with Once Should Generate code-like (A) _ m (0)?: _m (1) functiongenTernaryExp (EL) { // called again genElement () function return altGen ? altGen (EL, State) : el.once ? genOnce (EL, State) : genElement (EL, State) } }
Finally, rendering render function is:
_c ( 'div', {attrs: { "id": "app"}}?, [(no <0) _ c ( 'p', [_ v ( "n less than 0")]) :( no == 0 ?) _ c ( 'p', [_ v ( "no equals 0")]): _ c ( 'p', [_ v ( "no greater than 0")])])
among them
?? (No <0) _ c ( 'p', [_ v ( "n less than 0")]) :( no == 0) _ c ( 'p', [_ v ( "no equals 0")]): _ c ( 'p', [_ v ( "no greater than 0")])
It is an example where the corresponding v-if, v-else, v-else-if the structure