support v-else

This commit is contained in:
Evan You 2016-04-15 14:45:22 -04:00
parent 5590378d7f
commit b995ed3c9b
3 changed files with 45 additions and 5 deletions

View File

@ -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}}`

View File

@ -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) {

View File

@ -79,12 +79,16 @@ 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') {
if (element.else) {
processElse(element, currentParent)
} else {
currentParent.children.push(element)
}
}
if (!unary) {
currentParent = element
stack.push(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]
}
}