function getInnerChild(vnode: VNode) {
return vnode.shapeFlag & ShapeFlags.SUSPENSE ? vnode.ssContent! : vnode
}
- queuePostRenderEffect(() => {
- instance.isDeactivated = false
- if (instance.a) {
- invokeArrayFns(instance.a)
- }
- const vnodeHook = vnode.props && vnode.props.onVnodeMounted
- if (vnodeHook) {
- invokeVNodeHook(vnodeHook, instance.parent, vnode)
- }
- }, parentSuspense)
+
+/**
+ * shared between runtime-core and runtime-vapor
+ */
+export function activate(
+ vnode: VNode,
+ container: RendererElement,
+ anchor: RendererNode | null,
+ { p: patch, m: move }: RendererInternals,
+ parentComponent: ComponentInternalInstance | null,
+ parentSuspense: SuspenseBoundary | null,
+ namespace?: ElementNamespace,
+ optimized?: boolean,
+): void {
+ const instance = vnode.component!
+ move(
+ vnode,
+ container,
+ anchor,
+ MoveType.ENTER,
+ parentComponent,
+ parentSuspense,
+ )
+ // in case props have changed
+ patch(
+ instance.vnode,
+ vnode,
+ container,
+ anchor,
+ instance,
+ parentSuspense,
+ namespace,
+ vnode.slotScopeIds,
+ optimized,
+ )
- queuePostRenderEffect(() => {
- if (instance.da) {
- invokeArrayFns(instance.da)
- }
- const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted
- if (vnodeHook) {
- invokeVNodeHook(vnodeHook, instance.parent, vnode)
- }
- instance.isDeactivated = true
- }, parentSuspense)
++ queuePostRenderEffect(
++ () => {
++ instance.isDeactivated = false
++ if (instance.a) {
++ invokeArrayFns(instance.a)
++ }
++ const vnodeHook = vnode.props && vnode.props.onVnodeMounted
++ if (vnodeHook) {
++ invokeVNodeHook(vnodeHook, instance.parent, vnode)
++ }
++ },
++ undefined,
++ parentSuspense,
++ )
+
+ if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
+ // Update components tree
+ devtoolsComponentAdded(instance)
+ }
+}
+
+/**
+ * shared between runtime-core and runtime-vapor
+ */
+export function deactivate(
+ vnode: VNode,
+ container: RendererElement,
+ { m: move }: RendererInternals,
+ parentComponent: ComponentInternalInstance | null,
+ parentSuspense: SuspenseBoundary | null,
+): void {
+ const instance = vnode.component!
+ invalidateMount(instance.m)
+ invalidateMount(instance.a)
+
+ move(vnode, container, null, MoveType.LEAVE, parentComponent, parentSuspense)
++ queuePostRenderEffect(
++ () => {
++ if (instance.da) {
++ invokeArrayFns(instance.da)
++ }
++ const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted
++ if (vnodeHook) {
++ invokeVNodeHook(vnodeHook, instance.parent, vnode)
++ }
++ instance.isDeactivated = true
++ },
++ undefined,
++ parentSuspense,
++ )
+
+ if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
+ // Update components tree
+ devtoolsComponentAdded(instance)
+ }
+
+ // for e2e test
+ if (__DEV__ && __BROWSER__) {
+ ;(instance as any).__keepAliveStorageContainer = container
+ }
+}
unmountComponent,
} from './component'
import { createComment, createTextNode } from './dom/node'
- import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
+ import { EffectScope, setActiveSub } from '@vue/reactivity'
import { isHydrating } from './dom/hydration'
+import { isKeepAlive } from 'vue'
+import type { KeepAliveInstance } from './components/KeepAlive'
export type Block =
| Node
}
this.current = key
- pauseTracking()
+ const prevSub = setActiveSub()
const parent = this.anchor.parentNode
+ const instance = currentInstance!
// teardown previous branch
if (this.scope) {
- this.scope.stop()
+ if (isKeepAlive(instance)) {
+ ;(instance as KeepAliveInstance).process(this.nodes)
+ } else {
+ this.scope.stop()
+ }
parent && remove(this.nodes, parent)
}
currentInstance,
ensureRenderer,
isEmitListener,
+ isKeepAlive,
onScopeDispose,
renderSlot,
+ shallowReactive,
shallowRef,
simpleSetCurrentInstance,
+ activate as vdomActivate,
+ deactivate as vdomDeactivate,
} from '@vue/runtime-dom'
import {
type LooseRawProps,
import { renderEffect } from './renderEffect'
import { createTextNode } from './dom/node'
import { optimizePropertyLookup } from './dom/prop'
+import {
+ type KeepAliveInstance,
+ activate,
+ deactivate,
+} from './components/KeepAlive'
+import type { KeepAliveContext } from 'packages/runtime-core/src/components/KeepAlive'
+ export const interopKey: unique symbol = Symbol(`interop`)
+
// mounting vapor components and slots in vdom
const vaporInteropImpl: Omit<
VaporInteropInterface,
const prev = currentInstance
simpleSetCurrentInstance(parentComponent)
- const propsRef = shallowRef(vnode.props)
+ // filter out reserved props
+ const props: VNode['props'] = {}
+ for (const key in vnode.props) {
+ if (!isReservedProp(key)) {
+ props[key] = vnode.props[key]
+ }
+ }
+
+ const propsRef = shallowRef(props)
const slotsRef = shallowRef(vnode.children)
+ const dynamicPropSource: (() => any)[] & { [interopKey]?: boolean } = [
+ () => propsRef.value,
+ ]
+ // mark as interop props
+ dynamicPropSource[interopKey] = true
// @ts-expect-error
const instance = (vnode.component = createComponent(
vnode.type as any as VaporComponent,