From: daiwei Date: Wed, 16 Jul 2025 13:28:41 +0000 (+0800) Subject: chore: Merge branch 'minor' into edison/feat/vaporKeepAlive X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fedison%2Ffeat%2FvaporKeepAlive;p=thirdparty%2Fvuejs%2Fcore.git chore: Merge branch 'minor' into edison/feat/vaporKeepAlive --- 789d50c06659cc179de19f9ddbcaa409b70d468a diff --cc packages/runtime-core/src/components/KeepAlive.ts index 731da28b8f,f4244f360e..5cad49b967 --- a/packages/runtime-core/src/components/KeepAlive.ts +++ b/packages/runtime-core/src/components/KeepAlive.ts @@@ -449,91 -503,3 +453,99 @@@ export function resetShapeFlag(vnode: a function getInnerChild(vnode: VNode) { return vnode.shapeFlag & ShapeFlags.SUSPENSE ? vnode.ssContent! : vnode } + +/** + * 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(() => { - instance.isDeactivated = false - if (instance.a) { - invokeArrayFns(instance.a) - } - const vnodeHook = vnode.props && vnode.props.onVnodeMounted - if (vnodeHook) { - invokeVNodeHook(vnodeHook, instance.parent, vnode) - } - }, 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 - }, 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 + } +} diff --cc packages/runtime-vapor/src/block.ts index 9693bb1adc,e021ce84b0..1cfda886c3 --- a/packages/runtime-vapor/src/block.ts +++ b/packages/runtime-vapor/src/block.ts @@@ -7,10 -6,8 +7,10 @@@ import 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 @@@ -50,17 -47,12 +50,17 @@@ export class DynamicFragment extends Va } 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) } diff --cc packages/runtime-vapor/src/component.ts index 3f1e8e1acb,da57882c49..ec503d2e66 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@@ -31,18 -30,11 +31,17 @@@ import type ShallowRef, markRaw, onScopeDispose, - pauseTracking, proxyRefs, - resetTracking, + setActiveSub, unref, } from '@vue/reactivity' -import { EMPTY_OBJ, invokeArrayFns, isFunction, isString } from '@vue/shared' +import { + EMPTY_OBJ, + ShapeFlags, + invokeArrayFns, + isFunction, + isString, +} from '@vue/shared' import { type DynamicPropsSource, type RawProps, diff --cc packages/runtime-vapor/src/vdomInterop.ts index cb52d30484,1573a30692..446eb6a8ad --- a/packages/runtime-vapor/src/vdomInterop.ts +++ b/packages/runtime-vapor/src/vdomInterop.ts @@@ -14,13 -14,11 +14,14 @@@ import currentInstance, ensureRenderer, isEmitListener, + isKeepAlive, onScopeDispose, renderSlot, + shallowReactive, shallowRef, simpleSetCurrentInstance, + activate as vdomActivate, + deactivate as vdomDeactivate, } from '@vue/runtime-dom' import { type LooseRawProps, @@@ -44,13 -36,9 +45,15 @@@ import type { RawSlots, VaporSlot } fro 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, @@@ -62,17 -50,14 +65,22 @@@ 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,