Evan You 10 лет назад
Родитель
Сommit
b995ed3c9b

+ 7 - 1
src/compiler/codegen/directives/show.js

@@ -1,5 +1,11 @@
 export function show (el, dir) {
-  let code = `display:(${dir.value}?'':'none')`
+  patchNode(el, `display:(${dir.value}?'':'none')`)
+  if (el.elseBlock) {
+    patchNode(el.elseBlock, `display:(${dir.value}?'none':'')`)
+  }
+}
+
+function patchNode (el, code) {
   el.styleBinding = el.styleBinding
     ? el.styleBinding.replace(/}\s?$/, `${code},}`)
     : `{${code}}`

+ 7 - 1
src/compiler/codegen/index.js

@@ -25,7 +25,13 @@ function genElement (el) {
 function genIf (el) {
   const exp = el.if
   el.if = false // avoid recursion
-  return `(${exp}) ? ${genElement(el)} : null`
+  return `(${exp}) ? ${genElement(el)} : ${genElse(el)}`
+}
+
+function genElse (el) {
+  return el.elseBlock
+    ? genElement(el.elseBlock)
+    : 'null'
 }
 
 function genFor (el) {

+ 31 - 3
src/compiler/parser/index.js

@@ -79,11 +79,15 @@ export function parse (template, preserveWhitespace) {
       } else if (process.env.NODE_ENV !== 'production' && !stack.length && !warned) {
         warned = true
         console.error(
-          'Component template should contain exactly one root element:\n\n' + template
+          `Component template should contain exactly one root element:\n\n${template}`
         )
       }
       if (currentParent && tag !== 'script') {
-        currentParent.children.push(element)
+        if (element.else) {
+          processElse(element, currentParent)
+        } else {
+          currentParent.children.push(element)
+        }
       }
       if (!unary) {
         currentParent = element
@@ -155,6 +159,23 @@ function processIf (el) {
   if (exp) {
     el.if = exp
   }
+  if (getAndRemoveAttr(el, 'v-else') != null) {
+    el.else = true
+  }
+}
+
+function processElse (el, parent) {
+  const prev = findPrevElement(parent.children)
+  if (prev && (prev.if || prev.attrsMap['v-show'])) {
+    prev.elseBlock = el
+    if (!prev.if) {
+      parent.children.push(el)
+    }
+  } else if (process.env.NODE_ENV !== 'production') {
+    console.error(
+      `v-else used on element <${el.tag}> without corresponding v-if/v-show.`
+    )
+  }
 }
 
 function processRender (el) {
@@ -251,7 +272,7 @@ function makeAttrsMap (attrs) {
 
 function getAndRemoveAttr (el, attr) {
   let val
-  if ((val = el.attrsMap[attr])) {
+  if ((val = el.attrsMap[attr]) != null) {
     el.attrsMap[attr] = null
     const list = el.attrsList
     for (let i = 0, l = list.length; i < l; i++) {
@@ -263,3 +284,10 @@ function getAndRemoveAttr (el, attr) {
   }
   return val
 }
+
+function findPrevElement (children) {
+  let i = children.length
+  while (i--) {
+    if (children[i].tag) return children[i]
+  }
+}