From 602b58ebd1923dd48669755d5f5b67c5478cc625 Mon Sep 17 00:00:00 2001 From: HcySunYang Date: Tue, 23 Mar 2021 04:34:46 +0800 Subject: [PATCH] fix(compiler-core): fix the detection of forwarded slots with v-if or v-for (#3353) fix #3347 --- .../__tests__/transforms/vSlot.spec.ts | 21 ++++++++++++--- .../compiler-core/src/transforms/vSlot.ts | 27 +++++++++++++------ 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts index a14198c8adc..99fc009b504 100644 --- a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts @@ -15,6 +15,7 @@ import { transformElement } from '../../src/transforms/transformElement' import { transformOn } from '../../src/transforms/vOn' import { transformBind } from '../../src/transforms/vBind' import { transformExpression } from '../../src/transforms/transformExpression' +import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet' import { trackSlotScopes, trackVForSlotScopes @@ -34,6 +35,7 @@ function parseWithSlots(template: string, options: CompilerOptions = {}) { ...(options.prefixIdentifiers ? [trackVForSlotScopes, transformExpression] : []), + transformSlotOutlet, transformElement, trackSlotScopes ], @@ -737,9 +739,8 @@ describe('compiler: transform component slots', () => { expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot() }) - test('generate flag on forwarded slots', () => { - const { slots } = parseWithSlots(``) - expect(slots).toMatchObject({ + describe('forwarded slots', () => { + const toMatch = { type: NodeTypes.JS_OBJECT_EXPRESSION, properties: [ { @@ -751,6 +752,20 @@ describe('compiler: transform component slots', () => { value: { content: `3 /* FORWARDED */` } } ] + } + test(' tag only', () => { + const { slots } = parseWithSlots(``) + expect(slots).toMatchObject(toMatch) + }) + + test(' tag w/ v-if', () => { + const { slots } = parseWithSlots(``) + expect(slots).toMatchObject(toMatch) + }) + + test(' tag w/ v-for', () => { + const { slots } = parseWithSlots(``) + expect(slots).toMatchObject(toMatch) }) }) diff --git a/packages/compiler-core/src/transforms/vSlot.ts b/packages/compiler-core/src/transforms/vSlot.ts index 8e1596a2e9a..e6387be6c33 100644 --- a/packages/compiler-core/src/transforms/vSlot.ts +++ b/packages/compiler-core/src/transforms/vSlot.ts @@ -368,14 +368,25 @@ function buildDynamicSlot( function hasForwardedSlots(children: TemplateChildNode[]): boolean { for (let i = 0; i < children.length; i++) { const child = children[i] - if (child.type === NodeTypes.ELEMENT) { - if ( - child.tagType === ElementTypes.SLOT || - (child.tagType === ElementTypes.ELEMENT && - hasForwardedSlots(child.children)) - ) { - return true - } + switch (child.type) { + case NodeTypes.ELEMENT: + if ( + child.tagType === ElementTypes.SLOT || + (child.tagType === ElementTypes.ELEMENT && + hasForwardedSlots(child.children)) + ) { + 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