Skip to content

Commit 24041b7

Browse files
committed
fix(compiler-core): generate NEED_PATCH flag for element with vnode hooks
1 parent c2913d5 commit 24041b7

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

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

+5
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,11 @@ describe('compiler: element transform', () => {
780780
expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
781781
})
782782

783+
test('NEED_PATCH (vnode hooks)', () => {
784+
const { node } = parseWithBind(`<div @vnodeUpdated="foo" />`)
785+
expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
786+
})
787+
783788
test('HYDRATE_EVENTS', () => {
784789
// ignore click events (has dedicated fast path)
785790
const { node } = parseWithElementTransform(`<div @click="foo" />`, {

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

+14-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import {
2525
PatchFlagNames,
2626
isSymbol,
2727
isOn,
28-
isObject
28+
isObject,
29+
isReservedProp
2930
} from '@vue/shared'
3031
import { createCompilerError, ErrorCodes } from '../errors'
3132
import {
@@ -281,22 +282,31 @@ export function buildProps(
281282
let hasStyleBinding = false
282283
let hasHydrationEventBinding = false
283284
let hasDynamicKeys = false
285+
let hasVnodeHook = false
284286
const dynamicPropNames: string[] = []
285287

286288
const analyzePatchFlag = ({ key, value }: Property) => {
287289
if (isStaticExp(key)) {
288290
const name = key.content
291+
const isEventHandler = isOn(name)
289292
if (
290293
!isComponent &&
291-
isOn(name) &&
294+
isEventHandler &&
292295
// omit the flag for click handlers because hydration gives click
293296
// dedicated fast path.
294297
name.toLowerCase() !== 'onclick' &&
295298
// omit v-model handlers
296-
name !== 'onUpdate:modelValue'
299+
name !== 'onUpdate:modelValue' &&
300+
// omit onVnodeXXX hooks
301+
!isReservedProp(name)
297302
) {
298303
hasHydrationEventBinding = true
299304
}
305+
306+
if (isEventHandler && isReservedProp(name)) {
307+
hasVnodeHook = true
308+
}
309+
300310
if (
301311
value.type === NodeTypes.JS_CACHE_EXPRESSION ||
302312
((value.type === NodeTypes.SIMPLE_EXPRESSION ||
@@ -475,7 +485,7 @@ export function buildProps(
475485
}
476486
if (
477487
(patchFlag === 0 || patchFlag === PatchFlags.HYDRATE_EVENTS) &&
478-
(hasRef || runtimeDirectives.length > 0)
488+
(hasRef || hasVnodeHook || runtimeDirectives.length > 0)
479489
) {
480490
patchFlag |= PatchFlags.NEED_PATCH
481491
}

0 commit comments

Comments
 (0)