warn when template contains text outside root element (#5164)

* warn when template contains text outside root element

* fix warned flag

* make warn once a function
This commit is contained in:
AchillesJ 2017-03-13 15:42:46 +08:00 committed by Evan You
parent 025e763124
commit c6ab2e06d4
2 changed files with 32 additions and 13 deletions

View File

@ -63,6 +63,13 @@ export function parse (
let inPre = false
let warned = false
function warnOnce (msg) {
if (!warned) {
warned = true
warn(msg)
}
}
function endPre (element) {
// check pre state
if (element.pre) {
@ -146,17 +153,15 @@ export function parse (
}
function checkRootConstraints (el) {
if (process.env.NODE_ENV !== 'production' && !warned) {
if (process.env.NODE_ENV !== 'production') {
if (el.tag === 'slot' || el.tag === 'template') {
warned = true
warn(
warnOnce(
`Cannot use <${el.tag}> as component root element because it may ` +
'contain multiple nodes.'
)
}
if (el.attrsMap.hasOwnProperty('v-for')) {
warned = true
warn(
warnOnce(
'Cannot use v-for on stateful component root element because ' +
'it renders multiple elements.'
)
@ -176,9 +181,8 @@ export function parse (
exp: element.elseif,
block: element
})
} else if (process.env.NODE_ENV !== 'production' && !warned) {
warned = true
warn(
} else if (process.env.NODE_ENV !== 'production') {
warnOnce(
`Component template should contain exactly one root element. ` +
`If you are using v-if on multiple elements, ` +
`use v-else-if to chain them instead.`
@ -224,11 +228,16 @@ export function parse (
chars (text: string) {
if (!currentParent) {
if (process.env.NODE_ENV !== 'production' && !warned && text === template) {
warned = true
warn(
'Component template requires a root element, rather than just text.'
)
if (process.env.NODE_ENV !== 'production') {
if (text === template) {
warnOnce(
'Component template requires a root element, rather than just text.'
)
} else if ((text = text.trim())) {
warnOnce(
`text "${text}" outside root element will be ignored.`
)
}
}
return
}

View File

@ -77,6 +77,16 @@ describe('parser', () => {
expect('Component template requires a root element, rather than just text').toHaveBeenWarned()
})
it('warn text before root element', () => {
parse('before root {{ interpolation }}<div></div>', baseOptions)
expect('text "before root {{ interpolation }}" outside root element will be ignored.').toHaveBeenWarned()
})
it('warn text after root element', () => {
parse('<div></div>after root {{ interpolation }}', baseOptions)
expect('text "after root {{ interpolation }}" outside root element will be ignored.').toHaveBeenWarned()
})
it('warn multiple root elements', () => {
parse('<div></div><div></div>', baseOptions)
expect('Component template should contain exactly one root element').toHaveBeenWarned()