fix(compiler-core): generate NEED_PATCH flag for element with vnode hooks

This commit is contained in:
Evan You 2020-08-19 17:29:23 -04:00
parent c2913d57d1
commit 24041b7ac1
2 changed files with 19 additions and 4 deletions

View File

@ -780,6 +780,11 @@ describe('compiler: element transform', () => {
expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH)) expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
}) })
test('NEED_PATCH (vnode hooks)', () => {
const { node } = parseWithBind(`<div @vnodeUpdated="foo" />`)
expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
})
test('HYDRATE_EVENTS', () => { test('HYDRATE_EVENTS', () => {
// ignore click events (has dedicated fast path) // ignore click events (has dedicated fast path)
const { node } = parseWithElementTransform(`<div @click="foo" />`, { const { node } = parseWithElementTransform(`<div @click="foo" />`, {

View File

@ -25,7 +25,8 @@ import {
PatchFlagNames, PatchFlagNames,
isSymbol, isSymbol,
isOn, isOn,
isObject isObject,
isReservedProp
} from '@vue/shared' } from '@vue/shared'
import { createCompilerError, ErrorCodes } from '../errors' import { createCompilerError, ErrorCodes } from '../errors'
import { import {
@ -281,22 +282,31 @@ export function buildProps(
let hasStyleBinding = false let hasStyleBinding = false
let hasHydrationEventBinding = false let hasHydrationEventBinding = false
let hasDynamicKeys = false let hasDynamicKeys = false
let hasVnodeHook = false
const dynamicPropNames: string[] = [] const dynamicPropNames: string[] = []
const analyzePatchFlag = ({ key, value }: Property) => { const analyzePatchFlag = ({ key, value }: Property) => {
if (isStaticExp(key)) { if (isStaticExp(key)) {
const name = key.content const name = key.content
const isEventHandler = isOn(name)
if ( if (
!isComponent && !isComponent &&
isOn(name) && isEventHandler &&
// omit the flag for click handlers because hydration gives click // omit the flag for click handlers because hydration gives click
// dedicated fast path. // dedicated fast path.
name.toLowerCase() !== 'onclick' && name.toLowerCase() !== 'onclick' &&
// omit v-model handlers // omit v-model handlers
name !== 'onUpdate:modelValue' name !== 'onUpdate:modelValue' &&
// omit onVnodeXXX hooks
!isReservedProp(name)
) { ) {
hasHydrationEventBinding = true hasHydrationEventBinding = true
} }
if (isEventHandler && isReservedProp(name)) {
hasVnodeHook = true
}
if ( if (
value.type === NodeTypes.JS_CACHE_EXPRESSION || value.type === NodeTypes.JS_CACHE_EXPRESSION ||
((value.type === NodeTypes.SIMPLE_EXPRESSION || ((value.type === NodeTypes.SIMPLE_EXPRESSION ||
@ -475,7 +485,7 @@ export function buildProps(
} }
if ( if (
(patchFlag === 0 || patchFlag === PatchFlags.HYDRATE_EVENTS) && (patchFlag === 0 || patchFlag === PatchFlags.HYDRATE_EVENTS) &&
(hasRef || runtimeDirectives.length > 0) (hasRef || hasVnodeHook || runtimeDirectives.length > 0)
) { ) {
patchFlag |= PatchFlags.NEED_PATCH patchFlag |= PatchFlags.NEED_PATCH
} }