Skip to content

Commit 602b58e

Browse files
authored
fix(compiler-core): fix the detection of forwarded slots with v-if or v-for (#3353)
fix #3347
1 parent 6cb9475 commit 602b58e

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

packages/compiler-core/__tests__/transforms/vSlot.spec.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { transformElement } from '../../src/transforms/transformElement'
1515
import { transformOn } from '../../src/transforms/vOn'
1616
import { transformBind } from '../../src/transforms/vBind'
1717
import { transformExpression } from '../../src/transforms/transformExpression'
18+
import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet'
1819
import {
1920
trackSlotScopes,
2021
trackVForSlotScopes
@@ -34,6 +35,7 @@ function parseWithSlots(template: string, options: CompilerOptions = {}) {
3435
...(options.prefixIdentifiers
3536
? [trackVForSlotScopes, transformExpression]
3637
: []),
38+
transformSlotOutlet,
3739
transformElement,
3840
trackSlotScopes
3941
],
@@ -737,9 +739,8 @@ describe('compiler: transform component slots', () => {
737739
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
738740
})
739741

740-
test('generate flag on forwarded slots', () => {
741-
const { slots } = parseWithSlots(`<Comp><slot/></Comp>`)
742-
expect(slots).toMatchObject({
742+
describe('forwarded slots', () => {
743+
const toMatch = {
743744
type: NodeTypes.JS_OBJECT_EXPRESSION,
744745
properties: [
745746
{
@@ -751,6 +752,20 @@ describe('compiler: transform component slots', () => {
751752
value: { content: `3 /* FORWARDED */` }
752753
}
753754
]
755+
}
756+
test('<slot> tag only', () => {
757+
const { slots } = parseWithSlots(`<Comp><slot/></Comp>`)
758+
expect(slots).toMatchObject(toMatch)
759+
})
760+
761+
test('<slot> tag w/ v-if', () => {
762+
const { slots } = parseWithSlots(`<Comp><slot v-if="ok"/></Comp>`)
763+
expect(slots).toMatchObject(toMatch)
764+
})
765+
766+
test('<slot> tag w/ v-for', () => {
767+
const { slots } = parseWithSlots(`<Comp><slot v-for="a in b"/></Comp>`)
768+
expect(slots).toMatchObject(toMatch)
754769
})
755770
})
756771

packages/compiler-core/src/transforms/vSlot.ts

+19-8
Original file line numberDiff line numberDiff line change
@@ -368,14 +368,25 @@ function buildDynamicSlot(
368368
function hasForwardedSlots(children: TemplateChildNode[]): boolean {
369369
for (let i = 0; i < children.length; i++) {
370370
const child = children[i]
371-
if (child.type === NodeTypes.ELEMENT) {
372-
if (
373-
child.tagType === ElementTypes.SLOT ||
374-
(child.tagType === ElementTypes.ELEMENT &&
375-
hasForwardedSlots(child.children))
376-
) {
377-
return true
378-
}
371+
switch (child.type) {
372+
case NodeTypes.ELEMENT:
373+
if (
374+
child.tagType === ElementTypes.SLOT ||
375+
(child.tagType === ElementTypes.ELEMENT &&
376+
hasForwardedSlots(child.children))
377+
) {
378+
return true
379+
}
380+
break
381+
case NodeTypes.IF:
382+
if (hasForwardedSlots(child.branches)) return true
383+
break
384+
case NodeTypes.IF_BRANCH:
385+
case NodeTypes.FOR:
386+
if (hasForwardedSlots(child.children)) return true
387+
break
388+
default:
389+
break
379390
}
380391
}
381392
return false

0 commit comments

Comments
 (0)