]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-core): fix v-if + v-for on `<template>`
authorEvan You <yyx990803@gmail.com>
Sun, 19 Jul 2020 18:36:01 +0000 (14:36 -0400)
committerEvan You <yyx990803@gmail.com>
Sun, 19 Jul 2020 18:36:01 +0000 (14:36 -0400)
fix #1637

packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap
packages/compiler-core/__tests__/transforms/vFor.spec.ts
packages/compiler-core/src/transforms/vFor.ts
packages/compiler-core/src/transforms/vIf.ts

index 970048cf699e17e46ab79d869934a91b08e703d0..2e12ad16e0860349dc0e01d75ac18baf4ea9256a 100644 (file)
@@ -180,6 +180,22 @@ return function render(_ctx, _cache) {
 }"
 `;
 
+exports[`compiler: v-for codegen v-if + v-for on <template> 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+  with (_ctx) {
+    const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
+
+    return ok
+      ? (_openBlock(true), _createBlock(_Fragment, { key: 0 }, _renderList(list, (i) => {
+          return (_openBlock(), _createBlock(_Fragment, null, [], 64 /* STABLE_FRAGMENT */))
+        }), 256 /* UNKEYED_FRAGMENT */))
+      : _createCommentVNode(\\"v-if\\", true)
+  }
+}"
+`;
+
 exports[`compiler: v-for codegen value + key + index 1`] = `
 "const _Vue = Vue
 
index 2657c08fe9711a2b9e79b71fb332e6c4d4835dc8..f3168bb53cf820d3d967f5d7fda3164d54a97f97 100644 (file)
@@ -840,6 +840,44 @@ describe('compiler: v-for', () => {
       expect(generate(root).code).toMatchSnapshot()
     })
 
+    // 1637
+    test('v-if + v-for on <template>', () => {
+      const {
+        root,
+        node: { codegenNode }
+      } = parseWithForTransform(`<template v-if="ok" v-for="i in list"/>`)
+      expect(codegenNode).toMatchObject({
+        type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
+        test: { content: `ok` },
+        consequent: {
+          type: NodeTypes.VNODE_CALL,
+          props: createObjectMatcher({
+            key: `[0]`
+          }),
+          isBlock: true,
+          disableTracking: true,
+          patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+          children: {
+            type: NodeTypes.JS_CALL_EXPRESSION,
+            callee: RENDER_LIST,
+            arguments: [
+              { content: `list` },
+              {
+                type: NodeTypes.JS_FUNCTION_EXPRESSION,
+                params: [{ content: `i` }],
+                returns: {
+                  type: NodeTypes.VNODE_CALL,
+                  tag: FRAGMENT,
+                  isBlock: true
+                }
+              }
+            ]
+          }
+        }
+      })
+      expect(generate(root).code).toMatchSnapshot()
+    })
+
     test('v-for on element with custom directive', () => {
       const {
         root,
index d85964e5270e97b386084ddd903619901cc3126d..68fd3f4553400cd246fd2443fe68c3dfb40d0941 100644 (file)
@@ -82,7 +82,7 @@ export const transformFor = createStructuralDirectiveTransform(
         const isTemplate = isTemplateNode(node)
         const { children } = forNode
         const needFragmentWrapper =
-          children.length > 1 || children[0].type !== NodeTypes.ELEMENT
+          children.length !== 1 || children[0].type !== NodeTypes.ELEMENT
         const slotOutlet = isSlotOutlet(node)
           ? node
           : isTemplate &&
index 11165d417684863152f3fbe0e14adc814e102025..491772fca9213cd839b38181321905d90aa7df7c 100644 (file)
@@ -30,7 +30,7 @@ import {
   OPEN_BLOCK,
   TELEPORT
 } from '../runtimeHelpers'
-import { injectProp } from '../utils'
+import { injectProp, findDir } from '../utils'
 import { PatchFlags, PatchFlagNames } from '@vue/shared'
 
 export const transformIf = createStructuralDirectiveTransform(
@@ -166,7 +166,10 @@ function createIfBranch(node: ElementNode, dir: DirectiveNode): IfBranchNode {
     type: NodeTypes.IF_BRANCH,
     loc: node.loc,
     condition: dir.name === 'else' ? undefined : dir.exp,
-    children: node.tagType === ElementTypes.TEMPLATE ? node.children : [node]
+    children:
+      node.tagType === ElementTypes.TEMPLATE && !findDir(node, 'for')
+        ? node.children
+        : [node]
   }
 }