if (isReservedProp(key)) continue
hostPatchProp(el, key, props[key], null, isSVG)
}
- invokeDirectiveHook(props.vnodeBeforeMount, parentComponent, vnode)
+ if (props.vnodeBeforeMount != null) {
+ invokeDirectiveHook(props.vnodeBeforeMount, parentComponent, vnode)
+ }
}
if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
hostSetElementText(el, vnode.children as string)
)
}
hostInsert(el, container, anchor)
- if (props != null) {
- invokeDirectiveHook(props.vnodeMounted, parentComponent, vnode)
+ if (props != null && props.vnodeMounted != null) {
+ queuePostFlushCb(() => {
+ invokeDirectiveHook(props.vnodeMounted, parentComponent, vnode)
+ })
}
}
const oldProps = (n1 && n1.props) || EMPTY_OBJ
const newProps = n2.props || EMPTY_OBJ
+ if (newProps.vnodeBeforeUpdate != null) {
+ invokeDirectiveHook(newProps.vnodeBeforeUpdate, parentComponent, n2)
+ }
+
if (patchFlag) {
// the presence of a patchFlag means this element's render code was
// generated by the compiler and can take the fast path.
// full diff
patchChildren(n1, n2, el, null, parentComponent, isSVG)
}
+
+ if (newProps.vnodeUpdated != null) {
+ queuePostFlushCb(() => {
+ invokeDirectiveHook(newProps.vnodeUpdated, parentComponent, n2)
+ })
+ }
}
function patchProps(
parentComponent: ComponentInstance | null,
doRemove?: boolean
) {
+ const {
+ props,
+ ref,
+ type,
+ component,
+ children,
+ dynamicChildren,
+ shapeFlag,
+ anchor
+ } = vnode
+
// unset ref
- if (vnode.ref !== null && parentComponent !== null) {
- setRef(vnode.ref, null, parentComponent, null)
+ if (ref !== null && parentComponent !== null) {
+ setRef(ref, null, parentComponent, null)
}
- const instance = vnode.component
- if (instance != null) {
- unmountComponent(instance, doRemove)
+ if (component != null) {
+ unmountComponent(component, doRemove)
return
}
- const shouldRemoveChildren = vnode.type === Fragment && doRemove
- if (vnode.dynamicChildren != null) {
- unmountChildren(
- vnode.dynamicChildren,
- parentComponent,
- shouldRemoveChildren
- )
- } else if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
+ if (props != null && props.vnodeBeforeUnmount != null) {
+ invokeDirectiveHook(props.vnodeBeforeUnmount, parentComponent, vnode)
+ }
+
+ const shouldRemoveChildren = type === Fragment && doRemove
+ if (dynamicChildren != null) {
+ unmountChildren(dynamicChildren, parentComponent, shouldRemoveChildren)
+ } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
unmountChildren(
- vnode.children as VNode[],
+ children as VNode[],
parentComponent,
shouldRemoveChildren
)
if (doRemove) {
hostRemove(vnode.el)
- if (vnode.anchor != null) hostRemove(vnode.anchor)
+ if (anchor != null) hostRemove(anchor)
+ }
+
+ if (props != null && props.vnodeUnmounted != null) {
+ queuePostFlushCb(() => {
+ invokeDirectiveHook(props.vnodeUnmounted, parentComponent, vnode)
+ })
}
}
// exclusive with CLASS, STYLE and PROPS.
FULL_PROPS = 1 << 4,
+ // Indicates an element that only needs non-props patching, e.g. ref or
+ // directives (vnodeXXX hooks). It simply marks the vnode as "need patch",
+ // since every pathced vnode checks for refs and vnodeXXX hooks.
+ NEED_PATCH = 1 << 5,
+
// Indicates a fragment or element with keyed or partially-keyed v-for
// children
- KEYED = 1 << 5,
+ KEYED = 1 << 6,
// Indicates a fragment or element that contains unkeyed v-for children
- UNKEYED = 1 << 6,
+ UNKEYED = 1 << 7,
// Indicates a component with dynamic slots (e.g. slot that references a v-for
// iterated value, or dynamic slot names).
// Components with this flag are always force updated.
- DYNAMIC_SLOTS = 1 << 7,
-
- // Indicates an element with ref. This includes static string refs because the
- // refs object is refreshed on each update and all refs need to set again.
- REF = 1 << 8
+ DYNAMIC_SLOTS = 1 << 8
}
// runtime object for public consumption
CLASS: PatchFlags.CLASS,
STYLE: PatchFlags.STYLE,
PROPS: PatchFlags.PROPS,
+ NEED_PATCH: PatchFlags.NEED_PATCH,
FULL_PROPS: PatchFlags.FULL_PROPS,
KEYED: PatchFlags.KEYED,
- UNKEYED: PatchFlags.UNKEYED,
- REF: PatchFlags.REF
+ UNKEYED: PatchFlags.UNKEYED
}