Quellcode durchsuchen

fix(compiler-vapor): treat template v-for with single component child as component

daiwei vor 8 Monaten
Ursprung
Commit
48fd560ad8

+ 32 - 0
packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap

@@ -235,6 +235,38 @@ export function render(_ctx) {
 }"
 }"
 `;
 `;
 
 
+exports[`compiler: v-for > v-for on component 1`] = `
+"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, child as _child, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue';
+const t0 = _template(" ")
+
+export function render(_ctx) {
+  const _component_Comp = _resolveComponent("Comp")
+  const n0 = _createFor(() => (_ctx.list), (_for_item0) => {
+    const n3 = _createComponentWithFallback(_component_Comp)
+    const n2 = _child(n3)
+    _renderEffect(() => _setText(n2, _toDisplayString(_for_item0.value)))
+    return [n2, n3]
+  }, undefined, 2)
+  return n0
+}"
+`;
+
+exports[`compiler: v-for > v-for on template with single component child 1`] = `
+"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, child as _child, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue';
+const t0 = _template(" ")
+
+export function render(_ctx) {
+  const _component_Comp = _resolveComponent("Comp")
+  const n0 = _createFor(() => (_ctx.list), (_for_item0) => {
+    const n3 = _createComponentWithFallback(_component_Comp)
+    const n2 = _child(n3)
+    _renderEffect(() => _setText(n2, _toDisplayString(_for_item0.value)))
+    return [n2, n3]
+  }, undefined, 2)
+  return n0
+}"
+`;
+
 exports[`compiler: v-for > w/o value 1`] = `
 exports[`compiler: v-for > w/o value 1`] = `
 "import { createFor as _createFor, template as _template } from 'vue';
 "import { createFor as _createFor, template as _template } from 'vue';
 const t0 = _template("<div>item</div>", true)
 const t0 = _template("<div>item</div>", true)

+ 20 - 0
packages/compiler-vapor/__tests__/transforms/vFor.spec.ts

@@ -368,4 +368,24 @@ describe('compiler: v-for', () => {
       index: undefined,
       index: undefined,
     })
     })
   })
   })
+
+  test('v-for on component', () => {
+    const { code, ir } = compileWithVFor(
+      `<Comp v-for="item in list">{{item}}</Comp>`,
+    )
+    expect(code).matchSnapshot()
+    expect(
+      (ir.block.dynamic.children[0].operation as ForIRNode).component,
+    ).toBe(true)
+  })
+
+  test('v-for on template with single component child', () => {
+    const { code, ir } = compileWithVFor(
+      `<template v-for="item in list"><Comp>{{item}}</Comp></template>`,
+    )
+    expect(code).matchSnapshot()
+    expect(
+      (ir.block.dynamic.children[0].operation as ForIRNode).component,
+    ).toBe(true)
+  })
 })
 })

+ 7 - 1
packages/compiler-vapor/src/transforms/vFor.ts

@@ -47,7 +47,13 @@ export function processFor(
 
 
   const keyProp = findProp(node, 'key')
   const keyProp = findProp(node, 'key')
   const keyProperty = keyProp && propToExpression(keyProp)
   const keyProperty = keyProp && propToExpression(keyProp)
-  const isComponent = node.tagType === ElementTypes.COMPONENT
+  const isComponent =
+    node.tagType === ElementTypes.COMPONENT ||
+    // template v-for with a single component child
+    (node.tag === 'template' &&
+      node.children.length === 1 &&
+      node.children[0].type === 1 &&
+      node.children[0].tagType === ElementTypes.COMPONENT)
   context.node = node = wrapTemplate(node, ['for'])
   context.node = node = wrapTemplate(node, ['for'])
   context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
   context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
   const id = context.reference()
   const id = context.reference()