From: daiwei Date: Thu, 23 Jan 2025 03:35:22 +0000 (+0800) Subject: chore: cache buildSlots result X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7327a573fe27525f5dfe93bf8686324f4be7c0a5;p=thirdparty%2Fvuejs%2Fcore.git chore: cache buildSlots result --- diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index b3a9d326f6..fed8cd2cfc 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -153,6 +153,8 @@ export interface PlainElementNode extends BaseElementNode { export interface ComponentNode extends BaseElementNode { tagType: ElementTypes.COMPONENT + slots: SlotsExpression + hasDynamicSlots: boolean codegenNode: | VNodeCall | CacheExpression // when cached by v-once diff --git a/packages/compiler-core/src/transforms/transformElement.ts b/packages/compiler-core/src/transforms/transformElement.ts index 76ca1d4435..05b215db31 100644 --- a/packages/compiler-core/src/transforms/transformElement.ts +++ b/packages/compiler-core/src/transforms/transformElement.ts @@ -173,7 +173,10 @@ export const transformElement: NodeTransform = (node, context) => { vnodeTag !== KEEP_ALIVE if (shouldBuildAsSlots) { - const { slots, hasDynamicSlots } = buildSlots(node, context) + const { slots, hasDynamicSlots } = buildSlots( + node as ComponentNode, + context, + ) vnodeChildren = slots if (hasDynamicSlots) { patchFlag |= PatchFlags.DYNAMIC_SLOTS diff --git a/packages/compiler-core/src/transforms/vSkip.ts b/packages/compiler-core/src/transforms/vSkip.ts index 3e0951f8dd..6121dfaa0a 100644 --- a/packages/compiler-core/src/transforms/vSkip.ts +++ b/packages/compiler-core/src/transforms/vSkip.ts @@ -6,7 +6,6 @@ import { NodeTypes, type SimpleExpressionNode, type SkipNode, - type SlotsExpression, type TemplateChildNode, createConditionalExpression, createSimpleExpression, @@ -79,9 +78,8 @@ export function processSkip( // if not found, throw an error if (node.tagType === ElementTypes.COMPONENT) { const { slots } = buildSlots(node, context) - const genChildren = slots as SlotsExpression - if (genChildren.type === NodeTypes.JS_OBJECT_EXPRESSION) { - const prop = genChildren.properties.find( + if (slots.type === NodeTypes.JS_OBJECT_EXPRESSION) { + const prop = slots.properties.find( p => p.type === NodeTypes.JS_PROPERTY && p.key.type === NodeTypes.SIMPLE_EXPRESSION && diff --git a/packages/compiler-core/src/transforms/vSlot.ts b/packages/compiler-core/src/transforms/vSlot.ts index db367f39c0..1c264a3a1b 100644 --- a/packages/compiler-core/src/transforms/vSlot.ts +++ b/packages/compiler-core/src/transforms/vSlot.ts @@ -1,8 +1,8 @@ import { type CallExpression, + type ComponentNode, type ConditionalExpression, type DirectiveNode, - type ElementNode, ElementTypes, type ExpressionNode, type FunctionExpression, @@ -114,13 +114,20 @@ const buildClientSlotFn: SlotFnBuilder = (props, _vForExp, children, loc) => // Instead of being a DirectiveTransform, v-slot processing is called during // transformElement to build the slots object for a component. export function buildSlots( - node: ElementNode, + node: ComponentNode, context: TransformContext, buildSlotFn: SlotFnBuilder = buildClientSlotFn, ): { slots: SlotsExpression hasDynamicSlots: boolean } { + // return early if slots are already built to avoid duplication + if (node.slots) { + return { + slots: node.slots, + hasDynamicSlots: node.hasDynamicSlots, + } + } context.helper(WITH_CTX) const { children, loc } = node @@ -364,6 +371,8 @@ export function buildSlots( ]) as SlotsExpression } + node.slots = slots + node.hasDynamicSlots = hasDynamicSlots return { slots, hasDynamicSlots,