From 32ae16491e442eb37b5670a329d76dbb845d8bfd Mon Sep 17 00:00:00 2001 From: baiwusanyu-c <740132583@qq.com> Date: Wed, 24 May 2023 16:23:31 +0800 Subject: [PATCH 1/8] fix(compiler-core): Properly handle v-for and ref on templates --- .../compiler-core/src/transforms/vSlot.ts | 65 +++++++++++-------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/packages/compiler-core/src/transforms/vSlot.ts b/packages/compiler-core/src/transforms/vSlot.ts index c4416dd45..36f3beb27 100644 --- a/packages/compiler-core/src/transforms/vSlot.ts +++ b/packages/compiler-core/src/transforms/vSlot.ts @@ -1,39 +1,33 @@ import { - ElementNode, - ObjectExpression, + CallExpression, + ConditionalExpression, + createArrayExpression, + createCallExpression, + createConditionalExpression, + createFunctionExpression, createObjectExpression, - NodeTypes, createObjectProperty, createSimpleExpression, - createFunctionExpression, DirectiveNode, + ElementNode, ElementTypes, ExpressionNode, - Property, - TemplateChildNode, - SourceLocation, - createConditionalExpression, - ConditionalExpression, - SimpleExpressionNode, FunctionExpression, - CallExpression, - createCallExpression, - createArrayExpression, - SlotsExpression + NodeTypes, + ObjectExpression, + Property, + RenderSlotCall, + SimpleExpressionNode, + SlotsExpression, + SourceLocation, + TemplateChildNode, } from '../ast' -import { TransformContext, NodeTransform } from '../transform' -import { createCompilerError, ErrorCodes } from '../errors' -import { - findDir, - isTemplateNode, - assert, - isVSlot, - hasScopeRef, - isStaticExp -} from '../utils' -import { CREATE_SLOTS, RENDER_LIST, WITH_CTX } from '../runtimeHelpers' -import { parseForExpression, createForLoopParams } from './vFor' -import { SlotFlags, slotFlagsText } from '@vue/shared' +import {NodeTransform, TransformContext} from '../transform' +import {createCompilerError, ErrorCodes} from '../errors' +import {assert, findDir, findProp, hasScopeRef, injectProp, isStaticExp, isTemplateNode, isVSlot} from '../utils' +import {CREATE_SLOTS, RENDER_LIST, WITH_CTX} from '../runtimeHelpers' +import {createForLoopParams, parseForExpression} from './vFor' +import {SlotFlags, slotFlagsText} from '@vue/shared' const defaultFallback = createSimpleExpression(`undefined`, false) @@ -263,6 +257,8 @@ export function buildSlots( vFor.parseResult || parseForExpression(vFor.exp as SimpleExpressionNode, context) if (parseResult) { + // #8395 + injectRefFor(slotElement.children, context) // Render the dynamic slots as an array and add it to the createSlot() // args. The runtime knows how to handle it appropriately. dynamicSlots.push( @@ -422,3 +418,18 @@ function isNonWhitespaceContent(node: TemplateChildNode): boolean { ? !!node.content.trim() : isNonWhitespaceContent(node.content) } + +function injectRefFor( + children: TemplateChildNode[], + context: TransformContext){ + for (let i = 0; i < children.length; i++) { + const child = children[i] + if(child.type === NodeTypes.ELEMENT && findProp(child, 'ref') ){ + const Property = createObjectProperty( + createSimpleExpression('ref_for', true), + createSimpleExpression('true') + ) + injectProp(child.codegenNode as RenderSlotCall, Property, context) + } + } +} \ No newline at end of file From f3705b0990ff2f0e647a692fc65c8b7257de5271 Mon Sep 17 00:00:00 2001 From: baiwusanyu-c <740132583@qq.com> Date: Wed, 24 May 2023 16:50:24 +0800 Subject: [PATCH 2/8] fix(compiler-core): added unit test --- .../__snapshots__/vSlot.spec.ts.snap | 52 +++++++++++++++++++ .../__tests__/transforms/vSlot.spec.ts | 33 ++++++++++++ 2 files changed, 85 insertions(+) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap index 0c8e061f9..6eef9b71d 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap @@ -1,5 +1,57 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`compiler: transform component slots > Properly handle v-for and ref on template 1`] = ` +"const _Vue = Vue + +return function render(_ctx, _cache) { + with (_ctx) { + const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = _Vue + + const _component_Comp = _resolveComponent(\\"Comp\\") + + return (_openBlock(), _createBlock(_component_Comp, null, _createSlots({ _: 2 /* DYNAMIC */ }, [ + _renderList(_ctx.list, (name) => { + return { + name: name, + fn: _withCtx(() => [ + _createElementVNode(\\"p\\", { + ref_for: true, + ref: \\"slotItems\\" + }, _toDisplayString(name), 513 /* TEXT, NEED_PATCH */) + ]) + } + }) + ]), 1024 /* DYNAMIC_SLOTS */)) + } +}" +`; + +exports[`compiler: transform component slots > bwsy 1`] = ` +"const _Vue = Vue + +return function render(_ctx, _cache) { + with (_ctx) { + const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = _Vue + + const _component_Comp = _resolveComponent(\\"Comp\\") + + return (_openBlock(), _createBlock(_component_Comp, null, _createSlots({ _: 2 /* DYNAMIC */ }, [ + _renderList(_ctx.list, (name) => { + return { + name: name, + fn: _withCtx(() => [ + _createElementVNode(\\"strong\\", { + ref_for: true, + ref: \\"slotItems\\" + }, _toDisplayString(name), 513 /* TEXT, NEED_PATCH */) + ]) + } + }) + ]), 1024 /* DYNAMIC_SLOTS */)) + } +}" +`; + exports[`compiler: transform component slots > dynamically named slots 1`] = ` "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue diff --git a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts index bb3d9d2cf..4e924f6c2 100644 --- a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts @@ -371,6 +371,39 @@ describe('compiler: transform component slots', () => { expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot() }) + test('Properly handle v-for and ref on template', () => { + const { root, slots } = parseWithSlots( + ` + + `, + { prefixIdentifiers: true } + ) + + const spy = { + type: NodeTypes.JS_PROPERTY, + key: { + constType: 3, + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'ref_for', + isStatic: true + }, + value: { + constType: 0, + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'true', + isStatic: false + } + } + + const properties = (slots as any).arguments[1].elements[0].arguments[1] + .returns.properties[1].value.returns[0].codegenNode.props.properties[0] + expect(properties).toMatchObject(spy) + expect((root as any).children[0].codegenNode.patchFlag).toMatch( + PatchFlags.DYNAMIC_SLOTS + '' + ) + expect(generate(root).code).toMatchSnapshot() + }) + test('nested slots scoping', () => { const { root, slots } = parseWithSlots( ` From 08519738de098127de701abfe2f3c0ceed48c0ef Mon Sep 17 00:00:00 2001 From: baiwusanyu-c <740132583@qq.com> Date: Wed, 24 May 2023 16:53:22 +0800 Subject: [PATCH 3/8] fix(compiler-core): rollback format --- .../compiler-core/src/transforms/vSlot.ts | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/packages/compiler-core/src/transforms/vSlot.ts b/packages/compiler-core/src/transforms/vSlot.ts index 36f3beb27..f185d1d69 100644 --- a/packages/compiler-core/src/transforms/vSlot.ts +++ b/packages/compiler-core/src/transforms/vSlot.ts @@ -1,33 +1,41 @@ import { - CallExpression, - ConditionalExpression, - createArrayExpression, - createCallExpression, - createConditionalExpression, - createFunctionExpression, + ElementNode, + ObjectExpression, createObjectExpression, + NodeTypes, createObjectProperty, createSimpleExpression, + createFunctionExpression, DirectiveNode, - ElementNode, ElementTypes, ExpressionNode, - FunctionExpression, - NodeTypes, - ObjectExpression, Property, - RenderSlotCall, - SimpleExpressionNode, - SlotsExpression, - SourceLocation, TemplateChildNode, + SourceLocation, + createConditionalExpression, + ConditionalExpression, + SimpleExpressionNode, + FunctionExpression, + CallExpression, + createCallExpression, + createArrayExpression, + SlotsExpression, RenderSlotCall } from '../ast' -import {NodeTransform, TransformContext} from '../transform' -import {createCompilerError, ErrorCodes} from '../errors' -import {assert, findDir, findProp, hasScopeRef, injectProp, isStaticExp, isTemplateNode, isVSlot} from '../utils' -import {CREATE_SLOTS, RENDER_LIST, WITH_CTX} from '../runtimeHelpers' -import {createForLoopParams, parseForExpression} from './vFor' -import {SlotFlags, slotFlagsText} from '@vue/shared' +import { TransformContext, NodeTransform } from '../transform' +import { createCompilerError, ErrorCodes } from '../errors' +import { + findDir, + isTemplateNode, + assert, + isVSlot, + hasScopeRef, + isStaticExp, + findProp, + injectProp +} from '../utils' +import { CREATE_SLOTS, RENDER_LIST, WITH_CTX } from '../runtimeHelpers' +import { parseForExpression, createForLoopParams } from './vFor' +import { SlotFlags, slotFlagsText } from '@vue/shared' const defaultFallback = createSimpleExpression(`undefined`, false) From 496069727f5121ecdfedef51e8fe5bc37e13d93c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E9=9B=BE=E4=B8=89=E8=AF=AD?= <32354856+baiwusanyu-c@users.noreply.github.com> Date: Wed, 24 May 2023 16:55:18 +0800 Subject: [PATCH 4/8] Update vSlot.ts --- packages/compiler-core/src/transforms/vSlot.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/compiler-core/src/transforms/vSlot.ts b/packages/compiler-core/src/transforms/vSlot.ts index f185d1d69..8655054fd 100644 --- a/packages/compiler-core/src/transforms/vSlot.ts +++ b/packages/compiler-core/src/transforms/vSlot.ts @@ -19,7 +19,8 @@ import { CallExpression, createCallExpression, createArrayExpression, - SlotsExpression, RenderSlotCall + SlotsExpression, + RenderSlotCall, } from '../ast' import { TransformContext, NodeTransform } from '../transform' import { createCompilerError, ErrorCodes } from '../errors' @@ -440,4 +441,4 @@ function injectRefFor( injectProp(child.codegenNode as RenderSlotCall, Property, context) } } -} \ No newline at end of file +} From 343ad471a79f1b499f43d4e1bb8bf9c8fd62583d Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 07:35:32 +0000 Subject: [PATCH 5/8] [autofix.ci] apply automated fixes --- packages/compiler-core/src/transforms/vSlot.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/compiler-core/src/transforms/vSlot.ts b/packages/compiler-core/src/transforms/vSlot.ts index 8655054fd..8af654778 100644 --- a/packages/compiler-core/src/transforms/vSlot.ts +++ b/packages/compiler-core/src/transforms/vSlot.ts @@ -19,8 +19,8 @@ import { CallExpression, createCallExpression, createArrayExpression, - SlotsExpression, - RenderSlotCall, + SlotsExpression, + RenderSlotCall } from '../ast' import { TransformContext, NodeTransform } from '../transform' import { createCompilerError, ErrorCodes } from '../errors' @@ -430,10 +430,11 @@ function isNonWhitespaceContent(node: TemplateChildNode): boolean { function injectRefFor( children: TemplateChildNode[], - context: TransformContext){ + context: TransformContext +) { for (let i = 0; i < children.length; i++) { const child = children[i] - if(child.type === NodeTypes.ELEMENT && findProp(child, 'ref') ){ + if (child.type === NodeTypes.ELEMENT && findProp(child, 'ref')) { const Property = createObjectProperty( createSimpleExpression('ref_for', true), createSimpleExpression('true') From 7149f7e60ff6f2b697995822acbaa03b36913732 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 02:44:18 +0000 Subject: [PATCH 6/8] [autofix.ci] apply automated fixes --- .../__tests__/transforms/vSlot.spec.ts | 10 +++++----- packages/compiler-core/src/transforms/vSlot.ts | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts index f18b37eb6..de407776f 100644 --- a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts @@ -376,7 +376,7 @@ describe('compiler: transform component slots', () => { ` `, - { prefixIdentifiers: true } + { prefixIdentifiers: true }, ) const spy = { @@ -385,21 +385,21 @@ describe('compiler: transform component slots', () => { constType: 3, type: NodeTypes.SIMPLE_EXPRESSION, content: 'ref_for', - isStatic: true + isStatic: true, }, value: { constType: 0, type: NodeTypes.SIMPLE_EXPRESSION, content: 'true', - isStatic: false - } + isStatic: false, + }, } const properties = (slots as any).arguments[1].elements[0].arguments[1] .returns.properties[1].value.returns[0].codegenNode.props.properties[0] expect(properties).toMatchObject(spy) expect((root as any).children[0].codegenNode.patchFlag).toMatch( - PatchFlags.DYNAMIC_SLOTS + '' + PatchFlags.DYNAMIC_SLOTS + '', ) expect(generate(root).code).toMatchSnapshot() }) diff --git a/packages/compiler-core/src/transforms/vSlot.ts b/packages/compiler-core/src/transforms/vSlot.ts index 310b5749c..9f353fa74 100644 --- a/packages/compiler-core/src/transforms/vSlot.ts +++ b/packages/compiler-core/src/transforms/vSlot.ts @@ -9,6 +9,8 @@ import { NodeTypes, type ObjectExpression, type Property, + type RenderSlotCall, + SimpleExpressionNode, type SlotsExpression, type SourceLocation, type TemplateChildNode, @@ -19,22 +21,20 @@ import { createObjectExpression, createObjectProperty, createSimpleExpression, - SimpleExpressionNode, - RenderSlotCall } from '../ast' import type { NodeTransform, TransformContext } from '../transform' import { ErrorCodes, createCompilerError } from '../errors' import { assert, findDir, + findProp, hasScopeRef, + hasScopeRef, + injectProp, + isStaticExp, isStaticExp, isTemplateNode, isVSlot, - hasScopeRef, - isStaticExp, - findProp, - injectProp } from '../utils' import { CREATE_SLOTS, RENDER_LIST, WITH_CTX } from '../runtimeHelpers' import { createForLoopParams, finalizeForParseResult } from './vFor' @@ -434,14 +434,14 @@ function isNonWhitespaceContent(node: TemplateChildNode): boolean { function injectRefFor( children: TemplateChildNode[], - context: TransformContext + context: TransformContext, ) { for (let i = 0; i < children.length; i++) { const child = children[i] if (child.type === NodeTypes.ELEMENT && findProp(child, 'ref')) { const Property = createObjectProperty( createSimpleExpression('ref_for', true), - createSimpleExpression('true') + createSimpleExpression('true'), ) injectProp(child.codegenNode as RenderSlotCall, Property, context) } From d9e5763d352a4d5f7cdf78d95fd49430512a5855 Mon Sep 17 00:00:00 2001 From: baiwusanyu-c <740132583@qq.com> Date: Wed, 3 Jan 2024 15:32:52 +0800 Subject: [PATCH 7/8] chore: updated unit test snap --- .../__snapshots__/vSlot.spec.ts.snap | 180 +----------------- .../compiler-core/src/transforms/vSlot.ts | 3 - 2 files changed, 3 insertions(+), 180 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap index 923d6bda4..14ef4f380 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap @@ -7,16 +7,16 @@ return function render(_ctx, _cache) { with (_ctx) { const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = _Vue - const _component_Comp = _resolveComponent(\\"Comp\\") + const _component_Comp = _resolveComponent("Comp") return (_openBlock(), _createBlock(_component_Comp, null, _createSlots({ _: 2 /* DYNAMIC */ }, [ _renderList(_ctx.list, (name) => { return { name: name, fn: _withCtx(() => [ - _createElementVNode(\\"p\\", { + _createElementVNode("p", { ref_for: true, - ref: \\"slotItems\\" + ref: "slotItems" }, _toDisplayString(name), 513 /* TEXT, NEED_PATCH */) ]) } @@ -26,61 +26,6 @@ return function render(_ctx, _cache) { }" `; -exports[`compiler: transform component slots > bwsy 1`] = ` -"const _Vue = Vue - -return function render(_ctx, _cache) { - with (_ctx) { - const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = _Vue - - const _component_Comp = _resolveComponent(\\"Comp\\") - - return (_openBlock(), _createBlock(_component_Comp, null, _createSlots({ _: 2 /* DYNAMIC */ }, [ - _renderList(_ctx.list, (name) => { - return { - name: name, - fn: _withCtx(() => [ - _createElementVNode(\\"strong\\", { - ref_for: true, - ref: \\"slotItems\\" - }, _toDisplayString(name), 513 /* TEXT, NEED_PATCH */) - ]) - } - }) - ]), 1024 /* DYNAMIC_SLOTS */)) - } -}" -`; - -exports[`compiler: transform component slots > dynamically named slots 1`] = ` -"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue - -return function render(_ctx, _cache) { - const _component_Comp = _resolveComponent("Comp") - - return (_openBlock(), _createBlock(_component_Comp, null, { - [_ctx.one]: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)]), - [_ctx.two]: _withCtx(({ bar }) => [_toDisplayString(_ctx.foo), _toDisplayString(bar)]), - _: 2 /* DYNAMIC */ - }, 1024 /* DYNAMIC_SLOTS */)) -}" -`; - -exports[`compiler: transform component slots > implicit default slot 1`] = ` -"const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue - -return function render(_ctx, _cache) { - const _component_Comp = _resolveComponent("Comp") - - return (_openBlock(), _createBlock(_component_Comp, null, { - default: _withCtx(() => [ - _createElementVNode("div") - ]), - _: 1 /* STABLE */ - })) -}" -`; - exports[`compiler: transform component slots > named slot with v-for w/ prefixIdentifiers: true 1`] = ` "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = Vue @@ -170,27 +115,6 @@ return function render(_ctx, _cache) { }" `; -exports[`compiler: transform component slots > named slots w/ implicit default slot 1`] = ` -"const _Vue = Vue - -return function render(_ctx, _cache) { - with (_ctx) { - const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = _Vue - - const _component_Comp = _resolveComponent("Comp") - - return (_openBlock(), _createBlock(_component_Comp, null, { - one: _withCtx(() => ["foo"]), - default: _withCtx(() => [ - "bar", - _createElementVNode("span") - ]), - _: 1 /* STABLE */ - })) - } -}" -`; - exports[`compiler: transform component slots > nested slots scoping 1`] = ` "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue @@ -213,101 +137,3 @@ return function render(_ctx, _cache) { })) }" `; - -exports[`compiler: transform component slots > on component dynamically named slot 1`] = ` -"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue - -return function render(_ctx, _cache) { - const _component_Comp = _resolveComponent("Comp") - - return (_openBlock(), _createBlock(_component_Comp, null, { - [_ctx.named]: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)]), - _: 2 /* DYNAMIC */ - }, 1024 /* DYNAMIC_SLOTS */)) -}" -`; - -exports[`compiler: transform component slots > on component named slot 1`] = ` -"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue - -return function render(_ctx, _cache) { - const _component_Comp = _resolveComponent("Comp") - - return (_openBlock(), _createBlock(_component_Comp, null, { - named: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)]), - _: 1 /* STABLE */ - })) -}" -`; - -exports[`compiler: transform component slots > on-component default slot 1`] = ` -"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue - -return function render(_ctx, _cache) { - const _component_Comp = _resolveComponent("Comp") - - return (_openBlock(), _createBlock(_component_Comp, null, { - default: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)]), - _: 1 /* STABLE */ - })) -}" -`; - -exports[`compiler: transform component slots > template named slots 1`] = ` -"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue - -return function render(_ctx, _cache) { - const _component_Comp = _resolveComponent("Comp") - - return (_openBlock(), _createBlock(_component_Comp, null, { - one: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)]), - two: _withCtx(({ bar }) => [_toDisplayString(_ctx.foo), _toDisplayString(bar)]), - _: 1 /* STABLE */ - })) -}" -`; - -exports[`compiler: transform component slots > with whitespace: 'preserve' > implicit default slot 1`] = ` -"const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue - -return function render(_ctx, _cache) { - const _component_Comp = _resolveComponent("Comp") - - return (_openBlock(), _createBlock(_component_Comp, null, { - header: _withCtx(() => [" Header "]), - default: _withCtx(() => [ - " ", - _createElementVNode("p") - ]), - _: 1 /* STABLE */ - })) -}" -`; - -exports[`compiler: transform component slots > with whitespace: 'preserve' > named default slot + implicit whitespace content 1`] = ` -"const { resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue - -return function render(_ctx, _cache) { - const _component_Comp = _resolveComponent("Comp") - - return (_openBlock(), _createBlock(_component_Comp, null, { - header: _withCtx(() => [" Header "]), - default: _withCtx(() => [" Default "]), - _: 1 /* STABLE */ - })) -}" -`; - -exports[`compiler: transform component slots > with whitespace: 'preserve' > should not generate whitespace only default slot 1`] = ` -"const { resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue - -return function render(_ctx, _cache) { - const _component_Comp = _resolveComponent("Comp") - - return (_openBlock(), _createBlock(_component_Comp, null, { - header: _withCtx(() => [" Header "]), - footer: _withCtx(() => [" Footer "]), - _: 1 /* STABLE */ - })) -}" -`; diff --git a/packages/compiler-core/src/transforms/vSlot.ts b/packages/compiler-core/src/transforms/vSlot.ts index 9f353fa74..3d9d3b9f3 100644 --- a/packages/compiler-core/src/transforms/vSlot.ts +++ b/packages/compiler-core/src/transforms/vSlot.ts @@ -10,7 +10,6 @@ import { type ObjectExpression, type Property, type RenderSlotCall, - SimpleExpressionNode, type SlotsExpression, type SourceLocation, type TemplateChildNode, @@ -29,10 +28,8 @@ import { findDir, findProp, hasScopeRef, - hasScopeRef, injectProp, isStaticExp, - isStaticExp, isTemplateNode, isVSlot, } from '../utils' From 3003db20765d711ed73182de16973c1f36630345 Mon Sep 17 00:00:00 2001 From: baiwusanyu-c <740132583@qq.com> Date: Wed, 3 Jan 2024 15:37:17 +0800 Subject: [PATCH 8/8] chore: updated unit test snap --- .../__snapshots__/vSlot.spec.ts.snap | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap index 14ef4f380..2ec871e47 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap @@ -26,6 +26,35 @@ return function render(_ctx, _cache) { }" `; +exports[`compiler: transform component slots > dynamically named slots 1`] = ` +"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue + +return function render(_ctx, _cache) { + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, { + [_ctx.one]: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)]), + [_ctx.two]: _withCtx(({ bar }) => [_toDisplayString(_ctx.foo), _toDisplayString(bar)]), + _: 2 /* DYNAMIC */ + }, 1024 /* DYNAMIC_SLOTS */)) +}" +`; + +exports[`compiler: transform component slots > implicit default slot 1`] = ` +"const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue + +return function render(_ctx, _cache) { + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, { + default: _withCtx(() => [ + _createElementVNode("div") + ]), + _: 1 /* STABLE */ + })) +}" +`; + exports[`compiler: transform component slots > named slot with v-for w/ prefixIdentifiers: true 1`] = ` "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = Vue @@ -115,6 +144,27 @@ return function render(_ctx, _cache) { }" `; +exports[`compiler: transform component slots > named slots w/ implicit default slot 1`] = ` +"const _Vue = Vue + +return function render(_ctx, _cache) { + with (_ctx) { + const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = _Vue + + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, { + one: _withCtx(() => ["foo"]), + default: _withCtx(() => [ + "bar", + _createElementVNode("span") + ]), + _: 1 /* STABLE */ + })) + } +}" +`; + exports[`compiler: transform component slots > nested slots scoping 1`] = ` "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue @@ -137,3 +187,101 @@ return function render(_ctx, _cache) { })) }" `; + +exports[`compiler: transform component slots > on component dynamically named slot 1`] = ` +"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue + +return function render(_ctx, _cache) { + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, { + [_ctx.named]: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)]), + _: 2 /* DYNAMIC */ + }, 1024 /* DYNAMIC_SLOTS */)) +}" +`; + +exports[`compiler: transform component slots > on component named slot 1`] = ` +"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue + +return function render(_ctx, _cache) { + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, { + named: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)]), + _: 1 /* STABLE */ + })) +}" +`; + +exports[`compiler: transform component slots > on-component default slot 1`] = ` +"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue + +return function render(_ctx, _cache) { + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, { + default: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)]), + _: 1 /* STABLE */ + })) +}" +`; + +exports[`compiler: transform component slots > template named slots 1`] = ` +"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue + +return function render(_ctx, _cache) { + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, { + one: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)]), + two: _withCtx(({ bar }) => [_toDisplayString(_ctx.foo), _toDisplayString(bar)]), + _: 1 /* STABLE */ + })) +}" +`; + +exports[`compiler: transform component slots > with whitespace: 'preserve' > implicit default slot 1`] = ` +"const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue + +return function render(_ctx, _cache) { + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, { + header: _withCtx(() => [" Header "]), + default: _withCtx(() => [ + " ", + _createElementVNode("p") + ]), + _: 1 /* STABLE */ + })) +}" +`; + +exports[`compiler: transform component slots > with whitespace: 'preserve' > named default slot + implicit whitespace content 1`] = ` +"const { resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue + +return function render(_ctx, _cache) { + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, { + header: _withCtx(() => [" Header "]), + default: _withCtx(() => [" Default "]), + _: 1 /* STABLE */ + })) +}" +`; + +exports[`compiler: transform component slots > with whitespace: 'preserve' > should not generate whitespace only default slot 1`] = ` +"const { resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue + +return function render(_ctx, _cache) { + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, { + header: _withCtx(() => [" Header "]), + footer: _withCtx(() => [" Footer "]), + _: 1 /* STABLE */ + })) +}" +`;