fix(compiler-core): fix the detection of forwarded slots with v-if or v-for (#3353)

fix #3347
This commit is contained in:
HcySunYang 2021-03-23 04:34:46 +08:00 committed by GitHub
parent 6cb94752b0
commit 602b58ebd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 11 deletions

View File

@ -15,6 +15,7 @@ import { transformElement } from '../../src/transforms/transformElement'
import { transformOn } from '../../src/transforms/vOn' import { transformOn } from '../../src/transforms/vOn'
import { transformBind } from '../../src/transforms/vBind' import { transformBind } from '../../src/transforms/vBind'
import { transformExpression } from '../../src/transforms/transformExpression' import { transformExpression } from '../../src/transforms/transformExpression'
import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet'
import { import {
trackSlotScopes, trackSlotScopes,
trackVForSlotScopes trackVForSlotScopes
@ -34,6 +35,7 @@ function parseWithSlots(template: string, options: CompilerOptions = {}) {
...(options.prefixIdentifiers ...(options.prefixIdentifiers
? [trackVForSlotScopes, transformExpression] ? [trackVForSlotScopes, transformExpression]
: []), : []),
transformSlotOutlet,
transformElement, transformElement,
trackSlotScopes trackSlotScopes
], ],
@ -737,9 +739,8 @@ describe('compiler: transform component slots', () => {
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot() expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
}) })
test('generate flag on forwarded slots', () => { describe('forwarded slots', () => {
const { slots } = parseWithSlots(`<Comp><slot/></Comp>`) const toMatch = {
expect(slots).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION, type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [ properties: [
{ {
@ -751,6 +752,20 @@ describe('compiler: transform component slots', () => {
value: { content: `3 /* FORWARDED */` } value: { content: `3 /* FORWARDED */` }
} }
] ]
}
test('<slot> tag only', () => {
const { slots } = parseWithSlots(`<Comp><slot/></Comp>`)
expect(slots).toMatchObject(toMatch)
})
test('<slot> tag w/ v-if', () => {
const { slots } = parseWithSlots(`<Comp><slot v-if="ok"/></Comp>`)
expect(slots).toMatchObject(toMatch)
})
test('<slot> tag w/ v-for', () => {
const { slots } = parseWithSlots(`<Comp><slot v-for="a in b"/></Comp>`)
expect(slots).toMatchObject(toMatch)
}) })
}) })

View File

@ -368,14 +368,25 @@ function buildDynamicSlot(
function hasForwardedSlots(children: TemplateChildNode[]): boolean { function hasForwardedSlots(children: TemplateChildNode[]): boolean {
for (let i = 0; i < children.length; i++) { for (let i = 0; i < children.length; i++) {
const child = children[i] const child = children[i]
if (child.type === NodeTypes.ELEMENT) { switch (child.type) {
if ( case NodeTypes.ELEMENT:
child.tagType === ElementTypes.SLOT || if (
(child.tagType === ElementTypes.ELEMENT && child.tagType === ElementTypes.SLOT ||
hasForwardedSlots(child.children)) (child.tagType === ElementTypes.ELEMENT &&
) { hasForwardedSlots(child.children))
return true ) {
} return true
}
break
case NodeTypes.IF:
if (hasForwardedSlots(child.branches)) return true
break
case NodeTypes.IF_BRANCH:
case NodeTypes.FOR:
if (hasForwardedSlots(child.children)) return true
break
default:
break
} }
} }
return false return false