perf(v-on): constant handlers with modifiers should not be treated as dynamic

This commit is contained in:
Evan You 2023-11-30 19:26:36 +08:00
parent da4a4fb5e8
commit 4d94ebfe75
3 changed files with 41 additions and 6 deletions

View File

@ -1160,6 +1160,20 @@ describe('compiler: element transform', () => {
genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION]) 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', () => { describe('dynamic component', () => {

View File

@ -19,7 +19,8 @@ import {
TemplateTextChildNode, TemplateTextChildNode,
DirectiveArguments, DirectiveArguments,
createVNodeCall, createVNodeCall,
ConstantTypes ConstantTypes,
JSChildNode
} from '../ast' } from '../ast'
import { import {
PatchFlags, PatchFlags,
@ -459,6 +460,12 @@ export function buildProps(
hasVnodeHook = true 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 ( if (
value.type === NodeTypes.JS_CACHE_EXPRESSION || value.type === NodeTypes.JS_CACHE_EXPRESSION ||
((value.type === NodeTypes.SIMPLE_EXPRESSION || ((value.type === NodeTypes.SIMPLE_EXPRESSION ||

View File

@ -7,7 +7,8 @@ import {
NodeTypes, NodeTypes,
ObjectExpression, ObjectExpression,
transform, transform,
VNodeCall VNodeCall,
BindingTypes
} from '@vue/compiler-core' } from '@vue/compiler-core'
import { transformOn } from '../../src/transforms/vOn' import { transformOn } from '../../src/transforms/vOn'
import { V_ON_WITH_KEYS, V_ON_WITH_MODIFIERS } from '../../src/runtimeHelpers' import { V_ON_WITH_KEYS, V_ON_WITH_MODIFIERS } from '../../src/runtimeHelpers'
@ -25,12 +26,11 @@ function parseWithVOn(template: string, options: CompilerOptions = {}) {
}, },
...options ...options
}) })
const node = (ast.children[0] as ElementNode).codegenNode as VNodeCall
return { return {
root: ast, root: ast,
props: ( node,
((ast.children[0] as ElementNode).codegenNode as VNodeCall) props: (node.props as ObjectExpression).properties
.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))
})
}) })