@@ -25,7 +25,7 @@ import { SchedulerJobFlags } from '../scheduler'
2525
2626type Hook < T = ( ) => void > = T | T [ ]
2727
28- const leaveCbKey : unique symbol = Symbol ( '_leaveCb' )
28+ export const leaveCbKey : unique symbol = Symbol ( '_leaveCb' )
2929const enterCbKey : unique symbol = Symbol ( '_enterCb' )
3030
3131export interface BaseTransitionProps < HostElement = RendererElement > {
@@ -88,7 +88,7 @@ export interface TransitionState {
8888 isUnmounting : boolean
8989 // Track pending leave callbacks for children of the same key.
9090 // This is used to force remove leaving a child when a new copy is entering.
91- leavingVNodes : Map < any , Record < string , VNode > >
91+ leavingVNodes : Map < any , Record < string , any > >
9292}
9393
9494export interface TransitionElement {
@@ -319,6 +319,13 @@ function getLeavingNodesForType(
319319 return leavingVNodesCache
320320}
321321
322+ export interface TransitionHooksContext {
323+ setLeavingNodeCache : ( ) => void
324+ unsetLeavingNodeCache : ( ) => void
325+ earlyRemove : ( ) => void
326+ cloneHooks : ( node : any ) => TransitionHooks
327+ }
328+
322329// The transition hooks are attached to the vnode as vnode.transition
323330// and will be called at appropriate timing in the renderer.
324331export function resolveTransitionHooks (
@@ -328,6 +335,57 @@ export function resolveTransitionHooks(
328335 instance : GenericComponentInstance ,
329336 postClone ?: ( hooks : TransitionHooks ) => void ,
330337) : TransitionHooks {
338+ const key = String ( vnode . key )
339+ const leavingVNodesCache = getLeavingNodesForType ( state , vnode )
340+ const context : TransitionHooksContext = {
341+ setLeavingNodeCache : ( ) => {
342+ leavingVNodesCache [ key ] = vnode
343+ } ,
344+ unsetLeavingNodeCache : ( ) => {
345+ if ( leavingVNodesCache [ key ] === vnode ) {
346+ delete leavingVNodesCache [ key ]
347+ }
348+ } ,
349+ earlyRemove : ( ) => {
350+ const leavingVNode = leavingVNodesCache [ key ]
351+ if (
352+ leavingVNode &&
353+ isSameVNodeType ( vnode , leavingVNode ) &&
354+ ( leavingVNode . el as TransitionElement ) [ leaveCbKey ]
355+ ) {
356+ // force early removal (not cancelled)
357+ ; ( leavingVNode . el as TransitionElement ) [ leaveCbKey ] ! ( )
358+ }
359+ } ,
360+ cloneHooks : vnode => {
361+ const hooks = resolveTransitionHooks (
362+ vnode ,
363+ props ,
364+ state ,
365+ instance ,
366+ postClone ,
367+ )
368+ if ( postClone ) postClone ( hooks )
369+ return hooks
370+ } ,
371+ }
372+
373+ return baseResolveTransitionHooks ( context , props , state , instance )
374+ }
375+
376+ export function baseResolveTransitionHooks (
377+ context : TransitionHooksContext ,
378+ props : BaseTransitionProps < any > ,
379+ state : TransitionState ,
380+ instance : GenericComponentInstance ,
381+ ) : TransitionHooks {
382+ const {
383+ setLeavingNodeCache,
384+ unsetLeavingNodeCache,
385+ earlyRemove,
386+ cloneHooks,
387+ } = context
388+
331389 const {
332390 appear,
333391 mode,
@@ -345,8 +403,6 @@ export function resolveTransitionHooks(
345403 onAfterAppear,
346404 onAppearCancelled,
347405 } = props
348- const key = String ( vnode . key )
349- const leavingVNodesCache = getLeavingNodesForType ( state , vnode )
350406
351407 const callHook : TransitionHookCaller = ( hook , args ) => {
352408 hook &&
@@ -388,16 +444,7 @@ export function resolveTransitionHooks(
388444 el [ leaveCbKey ] ( true /* cancelled */ )
389445 }
390446 // for toggled element with same key (v-if)
391- const leavingVNode = leavingVNodesCache [ key ]
392- if (
393- leavingVNode &&
394- isSameVNodeType ( vnode , leavingVNode ) &&
395- // TODO refactor
396- ( ( leavingVNode . el || leavingVNode ) as TransitionElement ) [ leaveCbKey ]
397- ) {
398- // force early removal (not cancelled)
399- ; ( ( leavingVNode . el || leavingVNode ) as TransitionElement ) [ leaveCbKey ] ! ( )
400- }
447+ earlyRemove ( )
401448 callHook ( hook , [ el ] )
402449 } ,
403450
@@ -436,7 +483,7 @@ export function resolveTransitionHooks(
436483 } ,
437484
438485 leave ( el , remove ) {
439- const key = String ( vnode . key )
486+ // const key = String(vnode.key)
440487 if ( el [ enterCbKey ] ) {
441488 el [ enterCbKey ] ( true /* cancelled */ )
442489 }
@@ -455,28 +502,18 @@ export function resolveTransitionHooks(
455502 callHook ( onAfterLeave , [ el ] )
456503 }
457504 el [ leaveCbKey ] = undefined
458- if ( leavingVNodesCache [ key ] === vnode ) {
459- delete leavingVNodesCache [ key ]
460- }
505+ unsetLeavingNodeCache ( )
461506 } )
462- leavingVNodesCache [ key ] = vnode
507+ setLeavingNodeCache ( )
463508 if ( onLeave ) {
464509 callAsyncHook ( onLeave , [ el , done ] )
465510 } else {
466511 done ( )
467512 }
468513 } ,
469514
470- clone ( vnode ) {
471- const hooks = resolveTransitionHooks (
472- vnode ,
473- props ,
474- state ,
475- instance ,
476- postClone ,
477- )
478- if ( postClone ) postClone ( hooks )
479- return hooks
515+ clone ( node ) {
516+ return cloneHooks ( node )
480517 } ,
481518 }
482519
0 commit comments