Skip to content

Commit 4d94ebf

Browse files
committed
perf(v-on): constant handlers with modifiers should not be treated as dynamic
1 parent da4a4fb commit 4d94ebf

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed

packages/compiler-core/__tests__/transforms/transformElement.spec.ts

+14
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,20 @@ describe('compiler: element transform', () => {
11601160
genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION])
11611161
)
11621162
})
1163+
1164+
test('should not have PROPS patchflag for constant v-on handlers', () => {
1165+
const { node } = parseWithElementTransform(`<div @keydown="foo" />`, {
1166+
prefixIdentifiers: true,
1167+
bindingMetadata: {
1168+
foo: BindingTypes.SETUP_CONST
1169+
},
1170+
directiveTransforms: {
1171+
on: transformOn
1172+
}
1173+
})
1174+
// should only have hydration flag
1175+
expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_HYDRATION))
1176+
})
11631177
})
11641178

11651179
describe('dynamic component', () => {

packages/compiler-core/src/transforms/transformElement.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import {
1919
TemplateTextChildNode,
2020
DirectiveArguments,
2121
createVNodeCall,
22-
ConstantTypes
22+
ConstantTypes,
23+
JSChildNode
2324
} from '../ast'
2425
import {
2526
PatchFlags,
@@ -459,6 +460,12 @@ export function buildProps(
459460
hasVnodeHook = true
460461
}
461462

463+
if (isEventHandler && value.type === NodeTypes.JS_CALL_EXPRESSION) {
464+
// handler wrapped with internal helper e.g. withModifiers(fn)
465+
// extract the actual expression
466+
value = value.arguments[0] as JSChildNode
467+
}
468+
462469
if (
463470
value.type === NodeTypes.JS_CACHE_EXPRESSION ||
464471
((value.type === NodeTypes.SIMPLE_EXPRESSION ||

packages/compiler-dom/__tests__/transforms/vOn.spec.ts

+19-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
NodeTypes,
88
ObjectExpression,
99
transform,
10-
VNodeCall
10+
VNodeCall,
11+
BindingTypes
1112
} from '@vue/compiler-core'
1213
import { transformOn } from '../../src/transforms/vOn'
1314
import { V_ON_WITH_KEYS, V_ON_WITH_MODIFIERS } from '../../src/runtimeHelpers'
@@ -25,12 +26,11 @@ function parseWithVOn(template: string, options: CompilerOptions = {}) {
2526
},
2627
...options
2728
})
29+
const node = (ast.children[0] as ElementNode).codegenNode as VNodeCall
2830
return {
2931
root: ast,
30-
props: (
31-
((ast.children[0] as ElementNode).codegenNode as VNodeCall)
32-
.props as ObjectExpression
33-
).properties
32+
node,
33+
props: (node.props as ObjectExpression).properties
3434
}
3535
}
3636

@@ -288,4 +288,18 @@ describe('compiler-dom: transform v-on', () => {
288288
}
289289
})
290290
})
291+
292+
test('should not have PROPS patchFlag for constant v-on handlers with modifiers', () => {
293+
const { node } = parseWithVOn(`<div @keydown.up="foo" />`, {
294+
prefixIdentifiers: true,
295+
bindingMetadata: {
296+
foo: BindingTypes.SETUP_CONST
297+
},
298+
directiveTransforms: {
299+
on: transformOn
300+
}
301+
})
302+
// should only have hydration flag
303+
expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_HYDRATION))
304+
})
291305
})

0 commit comments

Comments
 (0)