From 7cee02438f585829590e2fbc45cde18f15dbcd63 Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 27 Feb 2025 22:31:45 +0800 Subject: [PATCH] wip: handle mode --- .../src/components/BaseTransition.ts | 5 +- packages/runtime-vapor/src/block.ts | 61 +++++++++++++------ .../src/components/Transition.ts | 32 +++++++++- 3 files changed, 75 insertions(+), 23 deletions(-) diff --git a/packages/runtime-core/src/components/BaseTransition.ts b/packages/runtime-core/src/components/BaseTransition.ts index ae89f36356..673d30a777 100644 --- a/packages/runtime-core/src/components/BaseTransition.ts +++ b/packages/runtime-core/src/components/BaseTransition.ts @@ -392,10 +392,11 @@ export function resolveTransitionHooks( if ( leavingVNode && isSameVNodeType(vnode, leavingVNode) && - (leavingVNode.el as TransitionElement)[leaveCbKey] + // TODO refactor + ((leavingVNode.el || leavingVNode) as TransitionElement)[leaveCbKey] ) { // force early removal (not cancelled) - ;(leavingVNode.el as TransitionElement)[leaveCbKey]!() + ;((leavingVNode.el || leavingVNode) as TransitionElement)[leaveCbKey]!() } callHook(hook, [el]) }, diff --git a/packages/runtime-vapor/src/block.ts b/packages/runtime-vapor/src/block.ts index a4cfcea1f9..383c4e8e9f 100644 --- a/packages/runtime-vapor/src/block.ts +++ b/packages/runtime-vapor/src/block.ts @@ -19,7 +19,16 @@ export type Block = ( | DynamicFragment | VaporComponentInstance | Block[] -) & { transition?: TransitionHooks } +) & + TransitionBlock + +export type TransitionBlock = { + transition?: TransitionHooks + applyLeavingHooks?: ( + block: Block, + afterLeaveCb: () => void, + ) => TransitionHooks +} export type BlockFn = (...args: any[]) => Block @@ -29,6 +38,10 @@ export class VaporFragment { insert?: (parent: ParentNode, anchor: Node | null) => void remove?: (parent?: ParentNode) => void transition?: TransitionHooks + applyLeavingHooks?: ( + block: Block, + afterLeaveCb: () => void, + ) => TransitionHooks constructor(nodes: Block) { this.nodes = nodes @@ -56,29 +69,39 @@ export class DynamicFragment extends VaporFragment { pauseTracking() const parent = this.anchor.parentNode + const renderNewBranch = () => { + if (render) { + this.scope = new EffectScope() + this.nodes = this.scope.run(render) || [] + if (parent) insert(this.nodes, parent, this.anchor, this.transition) + } else { + this.scope = undefined + this.nodes = [] + } + + if (this.fallback && !isValidBlock(this.nodes)) { + parent && remove(this.nodes, parent, this.transition) + this.nodes = + (this.scope || (this.scope = new EffectScope())).run(this.fallback) || + [] + parent && insert(this.nodes, parent, this.anchor, this.transition) + } + } + // teardown previous branch if (this.scope) { this.scope.stop() - parent && remove(this.nodes, parent, this.transition) - } - - if (render) { - this.scope = new EffectScope() - this.nodes = this.scope.run(render) || [] - if (parent) insert(this.nodes, parent, this.anchor, this.transition) - } else { - this.scope = undefined - this.nodes = [] - } - - if (this.fallback && !isValidBlock(this.nodes)) { - parent && remove(this.nodes, parent) - this.nodes = - (this.scope || (this.scope = new EffectScope())).run(this.fallback) || - [] - parent && insert(this.nodes, parent, this.anchor, this.transition) + if (this.transition && this.transition.mode) { + const transition = this.applyLeavingHooks!(this.nodes, renderNewBranch) + parent && remove(this.nodes, parent, transition) + resetTracking() + return + } else { + parent && remove(this.nodes, parent, this.transition) + } } + renderNewBranch() resetTracking() } } diff --git a/packages/runtime-vapor/src/components/Transition.ts b/packages/runtime-vapor/src/components/Transition.ts index 2eb87ebffe..00cf52414e 100644 --- a/packages/runtime-vapor/src/components/Transition.ts +++ b/packages/runtime-vapor/src/components/Transition.ts @@ -11,7 +11,10 @@ import type { Block } from '../block' import { isVaporComponent } from '../component' export const vaporTransitionImpl: VaporTransitionInterface = { - applyTransition: (props: TransitionProps, slots: { default: () => any }) => { + applyTransition: ( + props: TransitionProps, + slots: { default: () => Block }, + ) => { const children = slots.default && slots.default() if (!children) { return @@ -30,7 +33,32 @@ export const vaporTransitionImpl: VaporTransitionInterface = { ) setTransitionHooks(child, enterHooks) - // TODO handle mode + const { mode } = props + // TODO check mode + + child.applyLeavingHooks = (block: Block, afterLeaveCb: () => void) => { + let leavingHooks = resolveTransitionHooks( + block as any, + props, + state, + currentInstance!, + ) + setTransitionHooks(block, leavingHooks) + + if (mode === 'out-in') { + state.isLeaving = true + leavingHooks.afterLeave = () => { + state.isLeaving = false + afterLeaveCb() + delete leavingHooks.afterLeave + } + } else if (mode === 'in-out') { + leavingHooks.delayLeave = (block: Block, earlyRemove, delayedLeave) => { + // TODO delay leave + } + } + return leavingHooks + } return children }, -- 2.47.2