From: Evan You Date: Thu, 30 Nov 2023 11:26:36 +0000 (+0800) Subject: perf(v-on): constant handlers with modifiers should not be treated as dynamic X-Git-Tag: v3.3.10~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4d94ebfe75174b340d2b794e699cad1add3600a9;p=thirdparty%2Fvuejs%2Fcore.git perf(v-on): constant handlers with modifiers should not be treated as dynamic --- diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts index c83bdeebef..678d01cbc7 100644 --- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts @@ -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(`
`, { + 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', () => { diff --git a/packages/compiler-core/src/transforms/transformElement.ts b/packages/compiler-core/src/transforms/transformElement.ts index 2b5f23a617..ccede37777 100644 --- a/packages/compiler-core/src/transforms/transformElement.ts +++ b/packages/compiler-core/src/transforms/transformElement.ts @@ -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 || diff --git a/packages/compiler-dom/__tests__/transforms/vOn.spec.ts b/packages/compiler-dom/__tests__/transforms/vOn.spec.ts index 79ffcdef03..42b4cd7988 100644 --- a/packages/compiler-dom/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-dom/__tests__/transforms/vOn.spec.ts @@ -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(`
`, { + prefixIdentifiers: true, + bindingMetadata: { + foo: BindingTypes.SETUP_CONST + }, + directiveTransforms: { + on: transformOn + } + }) + // should only have hydration flag + expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_HYDRATION)) + }) })