mirror of
https://gitee.com/vuejs/vue.git
synced 2024-12-05 05:27:59 +08:00
Allow 2 root nodes with v-if and v-else (#3329)
* allow 2 root nodes with v-if and v-else * apply root constraints to 2nd root element with v-else
This commit is contained in:
parent
7b3cb27d8a
commit
3e06c575cb
@ -130,29 +130,37 @@ export function parse (
|
||||
processAttrs(element)
|
||||
}
|
||||
|
||||
// tree management
|
||||
if (!root) {
|
||||
root = element
|
||||
// check root element constraints
|
||||
function checkRootConstraints (el) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (tag === 'slot' || tag === 'template') {
|
||||
if (el.tag === 'slot' || el.tag === 'template') {
|
||||
warn(
|
||||
`Cannot use <${tag}> as component root element because it may ` +
|
||||
`Cannot use <${el.tag}> as component root element because it may ` +
|
||||
'contain multiple nodes:\n' + template
|
||||
)
|
||||
}
|
||||
if (element.attrsMap.hasOwnProperty('v-for')) {
|
||||
if (el.attrsMap.hasOwnProperty('v-for')) {
|
||||
warn(
|
||||
'Cannot use v-for on stateful component root element because ' +
|
||||
'it renders multiple elements:\n' + template
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tree management
|
||||
if (!root) {
|
||||
root = element
|
||||
checkRootConstraints(root)
|
||||
} else if (process.env.NODE_ENV !== 'production' && !stack.length && !warned) {
|
||||
warned = true
|
||||
warn(
|
||||
`Component template should contain exactly one root element:\n\n${template}`
|
||||
)
|
||||
// allow 2 root elements with v-if and v-else
|
||||
if ((root.attrsMap.hasOwnProperty('v-if') && element.attrsMap.hasOwnProperty('v-else'))) {
|
||||
checkRootConstraints(element)
|
||||
} else {
|
||||
warned = true
|
||||
warn(
|
||||
`Component template should contain exactly one root element:\n\n${template}`
|
||||
)
|
||||
}
|
||||
}
|
||||
if (currentParent && !element.forbidden) {
|
||||
if (element.else) {
|
||||
|
@ -76,6 +76,35 @@ describe('parser', () => {
|
||||
expect('Component template should contain exactly one root element').toHaveBeenWarned()
|
||||
})
|
||||
|
||||
it('warn multiple root elements', () => {
|
||||
parse('<div></div><div></div>', baseOptions)
|
||||
expect('Component template should contain exactly one root element:\n\n<div></div><div></div>').toHaveBeenWarned()
|
||||
})
|
||||
|
||||
it('not warn 2 root elements with v-if and v-else', () => {
|
||||
parse('<div v-if="1"></div><div v-else></div>', baseOptions)
|
||||
expect('Component template should contain exactly one root element:\n\n<div v-if="1"></div><div v-else></div>')
|
||||
.not.toHaveBeenWarned()
|
||||
})
|
||||
|
||||
it('warn 2 root elements with v-if', () => {
|
||||
parse('<div v-if="1"></div><div v-if="2"></div>', baseOptions)
|
||||
expect('Component template should contain exactly one root element:\n\n<div v-if="1"></div><div v-if="2"></div>')
|
||||
.toHaveBeenWarned()
|
||||
})
|
||||
|
||||
it('warn 3 root elements with v-if and v-else on first 2', () => {
|
||||
parse('<div v-if="1"></div><div v-else></div><div></div>', baseOptions)
|
||||
expect('Component template should contain exactly one root element:\n\n<div v-if="1"></div><div v-else></div><div></div>')
|
||||
.toHaveBeenWarned()
|
||||
})
|
||||
|
||||
it('warn 2 root elements with v-if and v-else with v-for on 2nd', () => {
|
||||
parse('<div v-if="1"></div><div v-else v-for="i in [1]"></div>', baseOptions)
|
||||
expect('Cannot use v-for on stateful component root element because it renders multiple elements:\n<div v-if="1"></div><div v-else v-for="i in [1]"></div>')
|
||||
.toHaveBeenWarned()
|
||||
})
|
||||
|
||||
it('warn <template> as root element', () => {
|
||||
parse('<template></template>', baseOptions)
|
||||
expect('Cannot use <template> as component root element').toHaveBeenWarned()
|
||||
|
Loading…
Reference in New Issue
Block a user