@@ -25,7 +25,8 @@ import {
25
25
PatchFlagNames ,
26
26
isSymbol ,
27
27
isOn ,
28
- isObject
28
+ isObject ,
29
+ isReservedProp
29
30
} from '@vue/shared'
30
31
import { createCompilerError , ErrorCodes } from '../errors'
31
32
import {
@@ -281,22 +282,31 @@ export function buildProps(
281
282
let hasStyleBinding = false
282
283
let hasHydrationEventBinding = false
283
284
let hasDynamicKeys = false
285
+ let hasVnodeHook = false
284
286
const dynamicPropNames : string [ ] = [ ]
285
287
286
288
const analyzePatchFlag = ( { key, value } : Property ) => {
287
289
if ( isStaticExp ( key ) ) {
288
290
const name = key . content
291
+ const isEventHandler = isOn ( name )
289
292
if (
290
293
! isComponent &&
291
- isOn ( name ) &&
294
+ isEventHandler &&
292
295
// omit the flag for click handlers because hydration gives click
293
296
// dedicated fast path.
294
297
name . toLowerCase ( ) !== 'onclick' &&
295
298
// omit v-model handlers
296
- name !== 'onUpdate:modelValue'
299
+ name !== 'onUpdate:modelValue' &&
300
+ // omit onVnodeXXX hooks
301
+ ! isReservedProp ( name )
297
302
) {
298
303
hasHydrationEventBinding = true
299
304
}
305
+
306
+ if ( isEventHandler && isReservedProp ( name ) ) {
307
+ hasVnodeHook = true
308
+ }
309
+
300
310
if (
301
311
value . type === NodeTypes . JS_CACHE_EXPRESSION ||
302
312
( ( value . type === NodeTypes . SIMPLE_EXPRESSION ||
@@ -475,7 +485,7 @@ export function buildProps(
475
485
}
476
486
if (
477
487
( patchFlag === 0 || patchFlag === PatchFlags . HYDRATE_EVENTS ) &&
478
- ( hasRef || runtimeDirectives . length > 0 )
488
+ ( hasRef || hasVnodeHook || runtimeDirectives . length > 0 )
479
489
) {
480
490
patchFlag |= PatchFlags . NEED_PATCH
481
491
}
0 commit comments