Просмотр исходного кода

fix(compiler-vapor): handle template children in Transition (#14606)

Jack 1 месяц назад
Родитель
Сommit
5fb8b338db

+ 52 - 0
packages/compiler-vapor/__tests__/transforms/TransformTransition.spec.ts

@@ -119,6 +119,46 @@ describe('compiler: transition', () => {
     )
   })
 
+  test('does not warn with template v-if containing one child', () => {
+    checkWarning(
+      `
+      <transition>
+        <template v-if="ok">
+          <div>hey</div>
+        </template>
+      </transition>
+      `,
+      false,
+    )
+  })
+
+  test('warns with template v-if containing multiple children', () => {
+    checkWarning(
+      `
+      <transition>
+        <template v-if="ok">
+          <div>hey</div>
+          <div>there</div>
+        </template>
+      </transition>
+      `,
+      true,
+    )
+  })
+
+  test('warns with template v-if containing v-for', () => {
+    checkWarning(
+      `
+      <transition>
+        <template v-if="ok">
+          <div v-for="i in items">hey</div>
+        </template>
+      </transition>
+      `,
+      true,
+    )
+  })
+
   test('warns with multiple templates', () => {
     checkWarning(
       `
@@ -131,6 +171,18 @@ describe('compiler: transition', () => {
     )
   })
 
+  test('does not warn with multiple templates containing one child each', () => {
+    checkWarning(
+      `
+      <transition>
+        <template v-if="a"><div>hey</div></template>
+        <template v-else><div>there</div></template>
+      </transition>
+      `,
+      false,
+    )
+  })
+
   test('warns if multiple children with v-if', () => {
     checkWarning(
       `

+ 13 - 10
packages/compiler-vapor/src/transforms/transformTransition.ts

@@ -32,13 +32,16 @@ function hasMultipleChildren(node: ElementNode): boolean {
 
   const first = children[0]
 
-  // has v-for
-  if (
-    children.length === 1 &&
-    first.type === NodeTypes.ELEMENT &&
-    (findDir(first, 'for') || isTemplateNode(first))
-  ) {
-    return true
+  if (children.length === 1 && first.type === NodeTypes.ELEMENT) {
+    // has v-for
+    if (findDir(first, 'for')) {
+      return true
+    }
+
+    // Template branches should be validated based on their rendered children.
+    if (isTemplateNode(first)) {
+      return hasMultipleChildren(first)
+    }
   }
 
   const hasElse = (node: ElementNode) =>
@@ -46,11 +49,11 @@ function hasMultipleChildren(node: ElementNode): boolean {
 
   // has v-if/v-else-if/v-else
   if (
+    children.length > 0 &&
     children.every(
       (c, index) =>
         c.type === NodeTypes.ELEMENT &&
-        // not template
-        !isTemplateNode(c) &&
+        (!isTemplateNode(c) || !hasMultipleChildren(c)) &&
         // not has v-for
         !findDir(c, 'for') &&
         // if the first child has v-if, the rest should also have v-else-if/v-else
@@ -60,5 +63,5 @@ function hasMultipleChildren(node: ElementNode): boolean {
     return false
   }
 
-  return children.length > 1
+  return children.length !== 1
 }