Procházet zdrojové kódy

allow 2 root nodes with v-if and v-else (#3887)

* allow 2 root nodes with v-if and v-else

* fix compiler-options test with less specific text
Chris Fritz před 9 roky
rodič
revize
de199f9bbd

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

@@ -153,8 +153,9 @@ export function parse (
         checkRootConstraints(root)
         checkRootConstraints(root)
       } else if (process.env.NODE_ENV !== 'production' && !stack.length && !warned) {
       } else if (process.env.NODE_ENV !== 'production' && !stack.length && !warned) {
         // allow 2 root elements with v-if and v-else
         // allow 2 root elements with v-if and v-else
-        if ((root.attrsMap.hasOwnProperty('v-if') && element.attrsMap.hasOwnProperty('v-else'))) {
+        if (root.if && element.else) {
           checkRootConstraints(element)
           checkRootConstraints(element)
+          root.elseBlock = element
         } else {
         } else {
           warned = true
           warned = true
           warn(
           warn(
@@ -201,10 +202,10 @@ export function parse (
 
 
     chars (text: string) {
     chars (text: string) {
       if (!currentParent) {
       if (!currentParent) {
-        if (process.env.NODE_ENV !== 'production' && !warned) {
+        if (process.env.NODE_ENV !== 'production' && !warned && text === template) {
           warned = true
           warned = true
           warn(
           warn(
-            'Component template should contain exactly one root element:\n\n' + template
+            'Component template requires a root element, rather than just text:\n\n' + template
           )
           )
         }
         }
         return
         return

+ 1 - 1
test/unit/modules/compiler/compiler-options.spec.js

@@ -118,7 +118,7 @@ describe('compile options', () => {
   it('should collect errors', () => {
   it('should collect errors', () => {
     let compiled = compile('hello')
     let compiled = compile('hello')
     expect(compiled.errors.length).toBe(1)
     expect(compiled.errors.length).toBe(1)
-    expect(compiled.errors[0]).toContain('should contain exactly one root element')
+    expect(compiled.errors[0]).toContain('root element')
 
 
     compiled = compile('<div v-if="a----">{{ b++++ }}</div>')
     compiled = compile('<div v-if="a----">{{ b++++ }}</div>')
     expect(compiled.errors.length).toBe(2)
     expect(compiled.errors.length).toBe(2)

+ 20 - 2
test/unit/modules/compiler/parser.spec.js

@@ -73,7 +73,7 @@ describe('parser', () => {
 
 
   it('not contain root element', () => {
   it('not contain root element', () => {
     parse('hello world', baseOptions)
     parse('hello world', baseOptions)
-    expect('Component template should contain exactly one root element').toHaveBeenWarned()
+    expect('Component template requires a root element, rather than just text').toHaveBeenWarned()
   })
   })
 
 
   it('warn multiple root elements', () => {
   it('warn multiple root elements', () => {
@@ -83,10 +83,28 @@ describe('parser', () => {
 
 
   it('not warn 2 root elements with v-if and v-else', () => {
   it('not warn 2 root elements with v-if and v-else', () => {
     parse('<div v-if="1"></div><div v-else></div>', baseOptions)
     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>')
+    expect('Component template should contain exactly one root element')
       .not.toHaveBeenWarned()
       .not.toHaveBeenWarned()
   })
   })
 
 
+  it('not warn 2 root elements with v-if and v-else on separate lines', () => {
+    parse(`
+      <div v-if="1"></div>
+      <div v-else></div>
+    `, baseOptions)
+    expect('Component template should contain exactly one root element')
+      .not.toHaveBeenWarned()
+  })
+
+  it('generate correct ast for 2 root elements with v-if and v-else on separate lines', () => {
+    const ast = parse(`
+      <div v-if="1"></div>
+      <p v-else></p>
+    `, baseOptions)
+    expect(ast.tag).toBe('div')
+    expect(ast.elseBlock.tag).toBe('p')
+  })
+
   it('warn 2 root elements with v-if', () => {
   it('warn 2 root elements with v-if', () => {
     parse('<div v-if="1"></div><div v-if="2"></div>', baseOptions)
     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>')
     expect('Component template should contain exactly one root element:\n\n<div v-if="1"></div><div v-if="2"></div>')