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])
)
})
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', () => {

View 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 ||

View 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))
})
})