]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
perf(v-on): constant handlers with modifiers should not be treated as dynamic
authorEvan You <yyx990803@gmail.com>
Thu, 30 Nov 2023 11:26:36 +0000 (19:26 +0800)
committerEvan You <yyx990803@gmail.com>
Thu, 30 Nov 2023 11:26:36 +0000 (19:26 +0800)
packages/compiler-core/__tests__/transforms/transformElement.spec.ts
packages/compiler-core/src/transforms/transformElement.ts
packages/compiler-dom/__tests__/transforms/vOn.spec.ts

index c83bdeebef2e755e36e19fc44debc9ca0dbdc9e9..678d01cbc7d727e86298ee3f86c79a6bfabc9f20 100644 (file)
@@ -1160,6 +1160,20 @@ describe('compiler: element transform', () => {
         genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION])
       )
     })
+
+    test('should not have PROPS patchflag for constant v-on handlers', () => {
+      const { node } = parseWithElementTransform(`<div @keydown="foo" />`, {
+        prefixIdentifiers: true,
+        bindingMetadata: {
+          foo: BindingTypes.SETUP_CONST
+        },
+        directiveTransforms: {
+          on: transformOn
+        }
+      })
+      // should only have hydration flag
+      expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_HYDRATION))
+    })
   })
 
   describe('dynamic component', () => {
index 2b5f23a6177c50502662fda38d668cb1260ce341..ccede37777dc5a91ad8cb8da6ee2cf2a5cea3fe2 100644 (file)
@@ -19,7 +19,8 @@ import {
   TemplateTextChildNode,
   DirectiveArguments,
   createVNodeCall,
-  ConstantTypes
+  ConstantTypes,
+  JSChildNode
 } from '../ast'
 import {
   PatchFlags,
@@ -459,6 +460,12 @@ export function buildProps(
         hasVnodeHook = true
       }
 
+      if (isEventHandler && value.type === NodeTypes.JS_CALL_EXPRESSION) {
+        // handler wrapped with internal helper e.g. withModifiers(fn)
+        // extract the actual expression
+        value = value.arguments[0] as JSChildNode
+      }
+
       if (
         value.type === NodeTypes.JS_CACHE_EXPRESSION ||
         ((value.type === NodeTypes.SIMPLE_EXPRESSION ||
index 79ffcdef03c94fbb1e79c8f3955882884e0fdcc1..42b4cd798886c9680fb2c84e9c12a5e98797d04f 100644 (file)
@@ -7,7 +7,8 @@ import {
   NodeTypes,
   ObjectExpression,
   transform,
-  VNodeCall
+  VNodeCall,
+  BindingTypes
 } from '@vue/compiler-core'
 import { transformOn } from '../../src/transforms/vOn'
 import { V_ON_WITH_KEYS, V_ON_WITH_MODIFIERS } from '../../src/runtimeHelpers'
@@ -25,12 +26,11 @@ function parseWithVOn(template: string, options: CompilerOptions = {}) {
     },
     ...options
   })
+  const node = (ast.children[0] as ElementNode).codegenNode as VNodeCall
   return {
     root: ast,
-    props: (
-      ((ast.children[0] as ElementNode).codegenNode as VNodeCall)
-        .props as ObjectExpression
-    ).properties
+    node,
+    props: (node.props as ObjectExpression).properties
   }
 }
 
@@ -288,4 +288,18 @@ describe('compiler-dom: transform v-on', () => {
       }
     })
   })
+
+  test('should not have PROPS patchFlag for constant v-on handlers with modifiers', () => {
+    const { node } = parseWithVOn(`<div @keydown.up="foo" />`, {
+      prefixIdentifiers: true,
+      bindingMetadata: {
+        foo: BindingTypes.SETUP_CONST
+      },
+      directiveTransforms: {
+        on: transformOn
+      }
+    })
+    // should only have hydration flag
+    expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_HYDRATION))
+  })
 })