]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
chore: avoid merge setStyle and setDynamicProps into existing render effect
authordaiwei <daiwei521@126.com>
Thu, 12 Dec 2024 00:53:51 +0000 (08:53 +0800)
committerdaiwei <daiwei521@126.com>
Thu, 12 Dec 2024 00:53:51 +0000 (08:53 +0800)
packages/compiler-vapor/src/generators/prop.ts
packages/compiler-vapor/src/transform.ts

index 90b39c77c3c6d99acaa21e56f7f967c0a50879e9..f2ef4948579096e1a5ac0fbfc8ed31e895feaf15 100644 (file)
@@ -161,11 +161,11 @@ export function genPropValue(
   )
 }
 
-function getRuntimeHelper(
+export function getRuntimeHelper(
   tag: string,
   keyName: string,
   modifier: '.' | '^' | undefined,
-) {
+): { helperName: VaporHelper; omitKey: boolean } {
   const tagName = tag.toUpperCase()
   let helperName: VaporHelper
   let omitKey = false
index 6714c03cc331ed5863cd01ee462d56c26c17b68a..f8484515c212d1d068d4ff16ee53ab1be39a2c03 100644 (file)
@@ -32,10 +32,12 @@ import {
   type IRSlots,
   type OperationNode,
   type RootIRNode,
+  type SetPropIRNode,
   type VaporDirectiveNode,
 } from './ir'
 import { isConstantExpression } from './utils'
 import { newBlock, newDynamic } from './transforms/utils'
+import { getRuntimeHelper } from './generators/prop'
 
 export type NodeTransform = (
   node: RootNode | TemplateChildNode,
@@ -156,7 +158,8 @@ export class TransformContext<T extends AllNode = AllNode> {
     const existing = this.block.effect.find(e =>
       looseEqual(e.identifiers, Array.from(ids)),
     )
-    if (existing) {
+    const canMerge = isMergeableOperation(operations)
+    if (existing && canMerge) {
       existing.operations.push(...operations)
     } else {
       this.block.effect.push({
@@ -314,3 +317,33 @@ function extractIdentifiers(ids: Set<string>, node: ExpressionNode) {
     ids.add((node as SimpleExpressionNode).content)
   }
 }
+
+function getSetPropHelperName(op: SetPropIRNode): string {
+  const {
+    prop: { key, modifier },
+    tag,
+  } = op
+
+  const { helperName } = getRuntimeHelper(tag, key.content, modifier)
+  return helperName
+}
+
+function isMergeableOperation(operations: OperationNode[]): boolean {
+  // setStyle and setDynamicProps can't be merged into existing render effect,
+  // because they don't need to cache deps value. the existing render effect may cache deps value.
+  if (operations.some(op => op.type === IRNodeTypes.SET_DYNAMIC_PROPS)) {
+    return false
+  }
+
+  if (
+    operations.some(
+      op =>
+        op.type === IRNodeTypes.SET_PROP &&
+        getSetPropHelperName(op) === 'setStyle',
+    )
+  ) {
+    return false
+  }
+
+  return true
+}