Skip to content

Commit f657781

Browse files
committed
fix(compiler): treat template v-for with single component child as component
Copied from vuejs/core#13914
1 parent d02e238 commit f657781

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

packages/compiler/src/transforms/vFor.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ export function processFor(
4545

4646
const keyProp = findProp(node, 'key')
4747
const keyProperty = keyProp && propToExpression(keyProp, context)
48-
const isComponent = isJSXComponent(node)
48+
const isComponent =
49+
isJSXComponent(node) ||
50+
// template v-for with a single component child
51+
isTemplateWithSingleComponent(node)
4952
const id = context.reference()
5053
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
5154
const [render, exitBlock] = createBranch(node, context, true)
@@ -117,3 +120,10 @@ export function getForParseResult(
117120
source,
118121
}
119122
}
123+
124+
function isTemplateWithSingleComponent(node: JSXElement): boolean {
125+
const nonCommentChildren = node.children.filter((c) => !isEmptyText(c))
126+
return (
127+
nonCommentChildren.length === 1 && isJSXComponent(nonCommentChildren[0])
128+
)
129+
}

packages/compiler/test/transforms/__snapshots__/vFor.spec.ts.snap

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,27 @@ exports[`compiler: v-for > v-for aliases w/ complex expressions 1`] = `
201201
return n0
202202
"
203203
`;
204+
205+
exports[`compiler: v-for > v-for on component 1`] = `
206+
"
207+
const n0 = _createFor(() => (list), (_for_item0) => {
208+
const n3 = _createComponent(Comp)
209+
const n2 = _child(n3)
210+
_setNodes(n2, () => (_for_item0.value))
211+
return [n2, n3]
212+
}, undefined, 2)
213+
return n0
214+
"
215+
`;
216+
217+
exports[`compiler: v-for > v-for on template with single component child 1`] = `
218+
"
219+
const n0 = _createFor(() => (list), (_for_item0) => {
220+
const n3 = _createComponent(Comp)
221+
const n2 = _child(n3)
222+
_setNodes(n2, () => (_for_item0.value))
223+
return [n2, n3]
224+
}, undefined, 2)
225+
return n0
226+
"
227+
`;

packages/compiler/test/transforms/vFor.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,4 +379,24 @@ describe('compiler: v-for', () => {
379379
})
380380
expect(code).toMatchSnapshot()
381381
})
382+
383+
test('v-for on component', () => {
384+
const { code, ir } = compileWithVFor(
385+
`<Comp v-for={item in list}>{item}</Comp>`,
386+
)
387+
expect(code).matchSnapshot()
388+
expect(
389+
(ir.block.dynamic.children[0].operation as ForIRNode).component,
390+
).toBe(true)
391+
})
392+
393+
test('v-for on template with single component child', () => {
394+
const { code, ir } = compileWithVFor(
395+
`<template v-for={item in list}><Comp>{item}</Comp></template>`,
396+
)
397+
expect(code).matchSnapshot()
398+
expect(
399+
(ir.block.dynamic.children[0].operation as ForIRNode).component,
400+
).toBe(true)
401+
})
382402
})

0 commit comments

Comments
 (0)