]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
Revert "Revert "chore: cache buildSlots result""
authordaiwei <daiwei521@126.com>
Thu, 23 Jan 2025 07:05:09 +0000 (15:05 +0800)
committerdaiwei <daiwei521@126.com>
Thu, 23 Jan 2025 07:05:09 +0000 (15:05 +0800)
This reverts commit 74e8bb44cb1500b5ca5852899f391f861bb1813b.

packages/compiler-core/src/ast.ts
packages/compiler-core/src/transforms/transformElement.ts
packages/compiler-core/src/transforms/vSkip.ts
packages/compiler-core/src/transforms/vSlot.ts

index b3a9d326f61112ef144cb74a9e709e214af12732..fed8cd2cfc2e7384d9d6703529e58f7df8ea8d72 100644 (file)
@@ -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
index 76ca1d44353da1b74d398fa4b4d567779eb77d61..05b215db31ac128fe564ed598ddf82aa72e94268 100644 (file)
@@ -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
index 3e0951f8dd66aa35e431eda20100bb40086249f3..6121dfaa0a2177d7ba572a61a8db48029f834aaa 100644 (file)
@@ -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 &&
index aa4ac478b61fe954c65e1e6c841b37a0e68d1ff0..b238247b9f4f111739226e0b493930f188fda3cf 100644 (file)
@@ -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,