refactor: refactor vnode hooks invocation

This commit is contained in:
Evan You 2020-03-18 09:51:17 -04:00
parent c1c8e87052
commit 6679799540
3 changed files with 29 additions and 23 deletions

View File

@ -11,7 +11,7 @@ return withDirectives(h(comp), [
]) ])
*/ */
import { VNode } from './vnode' import { VNode, VNodeHook } from './vnode'
import { isFunction, EMPTY_OBJ, makeMap, EMPTY_ARR } from '@vue/shared' import { isFunction, EMPTY_OBJ, makeMap, EMPTY_ARR } from '@vue/shared'
import { warn } from './warning' import { warn } from './warning'
import { ComponentInternalInstance, Data } from './component' import { ComponentInternalInstance, Data } from './component'
@ -154,7 +154,7 @@ export function withDirectives<T extends VNode>(
} }
export function invokeDirectiveHook( export function invokeDirectiveHook(
hook: ((...args: any[]) => any) | ((...args: any[]) => any)[], hook: VNodeHook | VNodeHook[],
instance: ComponentInternalInstance | null, instance: ComponentInternalInstance | null,
vnode: VNode, vnode: VNode,
prevVNode: VNode | null = null prevVNode: VNode | null = null

View File

@ -9,7 +9,8 @@ import {
createVNode, createVNode,
isSameVNodeType, isSameVNodeType,
Static, Static,
VNodeNormalizedRef VNodeNormalizedRef,
VNodeHook
} from './vnode' } from './vnode'
import { import {
ComponentInternalInstance, ComponentInternalInstance,
@ -524,6 +525,7 @@ function baseCreateRenderer<
optimized: boolean optimized: boolean
) => { ) => {
let el: HostElement let el: HostElement
let vnodeHook: VNodeHook | undefined | null
const { type, props, shapeFlag, transition, scopeId, patchFlag } = vnode const { type, props, shapeFlag, transition, scopeId, patchFlag } = vnode
if ( if (
vnode.el !== null && vnode.el !== null &&
@ -543,8 +545,8 @@ function baseCreateRenderer<
hostPatchProp(el, key, null, props[key], isSVG) hostPatchProp(el, key, null, props[key], isSVG)
} }
} }
if (props.onVnodeBeforeMount != null) { if ((vnodeHook = props.onVnodeBeforeMount) != null) {
invokeDirectiveHook(props.onVnodeBeforeMount, parentComponent, vnode) invokeDirectiveHook(vnodeHook, parentComponent, vnode)
} }
} }
@ -581,14 +583,12 @@ function baseCreateRenderer<
} }
hostInsert(el, container, anchor) hostInsert(el, container, anchor)
const vnodeMountedHook = props && props.onVnodeMounted
if ( if (
vnodeMountedHook != null || (vnodeHook = props && props.onVnodeMounted) != null ||
(transition != null && !transition.persisted) (transition != null && !transition.persisted)
) { ) {
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
vnodeMountedHook && vnodeHook && invokeDirectiveHook(vnodeHook, parentComponent, vnode)
invokeDirectiveHook(vnodeMountedHook, parentComponent, vnode)
transition && !transition.persisted && transition.enter(el) transition && !transition.persisted && transition.enter(el)
}, parentSuspense) }, parentSuspense)
} }
@ -633,9 +633,10 @@ function baseCreateRenderer<
let { patchFlag, dynamicChildren } = n2 let { patchFlag, dynamicChildren } = n2
const oldProps = (n1 && n1.props) || EMPTY_OBJ const oldProps = (n1 && n1.props) || EMPTY_OBJ
const newProps = n2.props || EMPTY_OBJ const newProps = n2.props || EMPTY_OBJ
let vnodeHook: VNodeHook | undefined | null
if (newProps.onVnodeBeforeUpdate != null) { if ((vnodeHook = newProps.onVnodeBeforeUpdate) != null) {
invokeDirectiveHook(newProps.onVnodeBeforeUpdate, parentComponent, n2, n1) invokeDirectiveHook(vnodeHook, parentComponent, n2, n1)
} }
if (__HMR__ && parentComponent && parentComponent.renderUpdated) { if (__HMR__ && parentComponent && parentComponent.renderUpdated) {
@ -749,9 +750,9 @@ function baseCreateRenderer<
) )
} }
if (newProps.onVnodeUpdated != null) { if ((vnodeHook = newProps.onVnodeUpdated) != null) {
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
invokeDirectiveHook(newProps.onVnodeUpdated, parentComponent, n2, n1) invokeDirectiveHook(vnodeHook!, parentComponent, n2, n1)
}, parentSuspense) }, parentSuspense)
} }
} }
@ -1617,6 +1618,7 @@ function baseCreateRenderer<
doRemove = false doRemove = false
) => { ) => {
const { props, ref, children, dynamicChildren, shapeFlag } = vnode const { props, ref, children, dynamicChildren, shapeFlag } = vnode
let vnodeHook: VNodeHook | undefined | null
// unset ref // unset ref
if (ref !== null && parentComponent !== null) { if (ref !== null && parentComponent !== null) {
@ -1637,8 +1639,8 @@ function baseCreateRenderer<
return return
} }
if (props != null && props.onVnodeBeforeUnmount != null) { if ((vnodeHook = props && props.onVnodeBeforeUnmount) != null) {
invokeDirectiveHook(props.onVnodeBeforeUnmount, parentComponent, vnode) invokeDirectiveHook(vnodeHook, parentComponent, vnode)
} }
if (dynamicChildren != null) { if (dynamicChildren != null) {
@ -1652,9 +1654,9 @@ function baseCreateRenderer<
remove(vnode) remove(vnode)
} }
if (props != null && props.onVnodeUnmounted != null) { if ((vnodeHook = props && props.onVnodeUnmounted) != null) {
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
invokeDirectiveHook(props.onVnodeUnmounted!, parentComponent, vnode) invokeDirectiveHook(vnodeHook!, parentComponent, vnode)
}, parentSuspense) }, parentSuspense)
} }
} }

View File

@ -59,18 +59,22 @@ export type VNodeRef =
export type VNodeNormalizedRef = [ComponentInternalInstance, VNodeRef] export type VNodeNormalizedRef = [ComponentInternalInstance, VNodeRef]
type VNodeMountHook = (vnode: VNode) => void
type VNodeUpdateHook = (vnode: VNode, oldVNode: VNode) => void
export type VNodeHook = VNodeMountHook | VNodeUpdateHook
export interface VNodeProps { export interface VNodeProps {
[key: string]: any [key: string]: any
key?: string | number key?: string | number
ref?: VNodeRef ref?: VNodeRef
// vnode hooks // vnode hooks
onVnodeBeforeMount?: (vnode: VNode) => void onVnodeBeforeMount?: VNodeMountHook
onVnodeMounted?: (vnode: VNode) => void onVnodeMounted?: VNodeMountHook
onVnodeBeforeUpdate?: (vnode: VNode, oldVNode: VNode) => void onVnodeBeforeUpdate?: VNodeUpdateHook
onVnodeUpdated?: (vnode: VNode, oldVNode: VNode) => void onVnodeUpdated?: VNodeUpdateHook
onVnodeBeforeUnmount?: (vnode: VNode) => void onVnodeBeforeUnmount?: VNodeMountHook
onVnodeUnmounted?: (vnode: VNode) => void onVnodeUnmounted?: VNodeMountHook
} }
type VNodeChildAtom<HostNode, HostElement> = type VNodeChildAtom<HostNode, HostElement> =