mirror of https://github.com/vuejs/core.git
				
				
				
			refactor: reuse code from BaseTransition
This commit is contained in:
		
							parent
							
								
									7cee02438f
								
							
						
					
					
						commit
						a8140ac826
					
				| 
						 | 
					@ -25,7 +25,7 @@ import { SchedulerJobFlags } from '../scheduler'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Hook<T = () => void> = T | T[]
 | 
					type Hook<T = () => void> = T | T[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const leaveCbKey: unique symbol = Symbol('_leaveCb')
 | 
					export const leaveCbKey: unique symbol = Symbol('_leaveCb')
 | 
				
			||||||
const enterCbKey: unique symbol = Symbol('_enterCb')
 | 
					const enterCbKey: unique symbol = Symbol('_enterCb')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface BaseTransitionProps<HostElement = RendererElement> {
 | 
					export interface BaseTransitionProps<HostElement = RendererElement> {
 | 
				
			||||||
| 
						 | 
					@ -88,7 +88,7 @@ export interface TransitionState {
 | 
				
			||||||
  isUnmounting: boolean
 | 
					  isUnmounting: boolean
 | 
				
			||||||
  // Track pending leave callbacks for children of the same key.
 | 
					  // Track pending leave callbacks for children of the same key.
 | 
				
			||||||
  // This is used to force remove leaving a child when a new copy is entering.
 | 
					  // This is used to force remove leaving a child when a new copy is entering.
 | 
				
			||||||
  leavingVNodes: Map<any, Record<string, VNode>>
 | 
					  leavingVNodes: Map<any, Record<string, any>>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface TransitionElement {
 | 
					export interface TransitionElement {
 | 
				
			||||||
| 
						 | 
					@ -319,6 +319,13 @@ function getLeavingNodesForType(
 | 
				
			||||||
  return leavingVNodesCache
 | 
					  return leavingVNodesCache
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface TransitionHooksContext {
 | 
				
			||||||
 | 
					  setLeavingNodeCache: () => void
 | 
				
			||||||
 | 
					  unsetLeavingNodeCache: () => void
 | 
				
			||||||
 | 
					  earlyRemove: () => void
 | 
				
			||||||
 | 
					  cloneHooks: (node: any) => TransitionHooks
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The transition hooks are attached to the vnode as vnode.transition
 | 
					// The transition hooks are attached to the vnode as vnode.transition
 | 
				
			||||||
// and will be called at appropriate timing in the renderer.
 | 
					// and will be called at appropriate timing in the renderer.
 | 
				
			||||||
export function resolveTransitionHooks(
 | 
					export function resolveTransitionHooks(
 | 
				
			||||||
| 
						 | 
					@ -328,6 +335,57 @@ export function resolveTransitionHooks(
 | 
				
			||||||
  instance: GenericComponentInstance,
 | 
					  instance: GenericComponentInstance,
 | 
				
			||||||
  postClone?: (hooks: TransitionHooks) => void,
 | 
					  postClone?: (hooks: TransitionHooks) => void,
 | 
				
			||||||
): TransitionHooks {
 | 
					): TransitionHooks {
 | 
				
			||||||
 | 
					  const key = String(vnode.key)
 | 
				
			||||||
 | 
					  const leavingVNodesCache = getLeavingNodesForType(state, vnode)
 | 
				
			||||||
 | 
					  const context: TransitionHooksContext = {
 | 
				
			||||||
 | 
					    setLeavingNodeCache: () => {
 | 
				
			||||||
 | 
					      leavingVNodesCache[key] = vnode
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    unsetLeavingNodeCache: () => {
 | 
				
			||||||
 | 
					      if (leavingVNodesCache[key] === vnode) {
 | 
				
			||||||
 | 
					        delete leavingVNodesCache[key]
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    earlyRemove: () => {
 | 
				
			||||||
 | 
					      const leavingVNode = leavingVNodesCache[key]
 | 
				
			||||||
 | 
					      if (
 | 
				
			||||||
 | 
					        leavingVNode &&
 | 
				
			||||||
 | 
					        isSameVNodeType(vnode, leavingVNode) &&
 | 
				
			||||||
 | 
					        (leavingVNode.el as TransitionElement)[leaveCbKey]
 | 
				
			||||||
 | 
					      ) {
 | 
				
			||||||
 | 
					        // force early removal (not cancelled)
 | 
				
			||||||
 | 
					        ;(leavingVNode.el as TransitionElement)[leaveCbKey]!()
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    cloneHooks: vnode => {
 | 
				
			||||||
 | 
					      const hooks = resolveTransitionHooks(
 | 
				
			||||||
 | 
					        vnode,
 | 
				
			||||||
 | 
					        props,
 | 
				
			||||||
 | 
					        state,
 | 
				
			||||||
 | 
					        instance,
 | 
				
			||||||
 | 
					        postClone,
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      if (postClone) postClone(hooks)
 | 
				
			||||||
 | 
					      return hooks
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return baseResolveTransitionHooks(context, props, state, instance)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function baseResolveTransitionHooks(
 | 
				
			||||||
 | 
					  context: TransitionHooksContext,
 | 
				
			||||||
 | 
					  props: BaseTransitionProps<any>,
 | 
				
			||||||
 | 
					  state: TransitionState,
 | 
				
			||||||
 | 
					  instance: GenericComponentInstance,
 | 
				
			||||||
 | 
					): TransitionHooks {
 | 
				
			||||||
 | 
					  const {
 | 
				
			||||||
 | 
					    setLeavingNodeCache,
 | 
				
			||||||
 | 
					    unsetLeavingNodeCache,
 | 
				
			||||||
 | 
					    earlyRemove,
 | 
				
			||||||
 | 
					    cloneHooks,
 | 
				
			||||||
 | 
					  } = context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const {
 | 
					  const {
 | 
				
			||||||
    appear,
 | 
					    appear,
 | 
				
			||||||
    mode,
 | 
					    mode,
 | 
				
			||||||
| 
						 | 
					@ -345,8 +403,6 @@ export function resolveTransitionHooks(
 | 
				
			||||||
    onAfterAppear,
 | 
					    onAfterAppear,
 | 
				
			||||||
    onAppearCancelled,
 | 
					    onAppearCancelled,
 | 
				
			||||||
  } = props
 | 
					  } = props
 | 
				
			||||||
  const key = String(vnode.key)
 | 
					 | 
				
			||||||
  const leavingVNodesCache = getLeavingNodesForType(state, vnode)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const callHook: TransitionHookCaller = (hook, args) => {
 | 
					  const callHook: TransitionHookCaller = (hook, args) => {
 | 
				
			||||||
    hook &&
 | 
					    hook &&
 | 
				
			||||||
| 
						 | 
					@ -388,16 +444,7 @@ export function resolveTransitionHooks(
 | 
				
			||||||
        el[leaveCbKey](true /* cancelled */)
 | 
					        el[leaveCbKey](true /* cancelled */)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      // for toggled element with same key (v-if)
 | 
					      // for toggled element with same key (v-if)
 | 
				
			||||||
      const leavingVNode = leavingVNodesCache[key]
 | 
					      earlyRemove()
 | 
				
			||||||
      if (
 | 
					 | 
				
			||||||
        leavingVNode &&
 | 
					 | 
				
			||||||
        isSameVNodeType(vnode, leavingVNode) &&
 | 
					 | 
				
			||||||
        // TODO refactor
 | 
					 | 
				
			||||||
        ((leavingVNode.el || leavingVNode) as TransitionElement)[leaveCbKey]
 | 
					 | 
				
			||||||
      ) {
 | 
					 | 
				
			||||||
        // force early removal (not cancelled)
 | 
					 | 
				
			||||||
        ;((leavingVNode.el || leavingVNode) as TransitionElement)[leaveCbKey]!()
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      callHook(hook, [el])
 | 
					      callHook(hook, [el])
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -436,7 +483,7 @@ export function resolveTransitionHooks(
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    leave(el, remove) {
 | 
					    leave(el, remove) {
 | 
				
			||||||
      const key = String(vnode.key)
 | 
					      // const key = String(vnode.key)
 | 
				
			||||||
      if (el[enterCbKey]) {
 | 
					      if (el[enterCbKey]) {
 | 
				
			||||||
        el[enterCbKey](true /* cancelled */)
 | 
					        el[enterCbKey](true /* cancelled */)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -455,11 +502,9 @@ export function resolveTransitionHooks(
 | 
				
			||||||
          callHook(onAfterLeave, [el])
 | 
					          callHook(onAfterLeave, [el])
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        el[leaveCbKey] = undefined
 | 
					        el[leaveCbKey] = undefined
 | 
				
			||||||
        if (leavingVNodesCache[key] === vnode) {
 | 
					        unsetLeavingNodeCache()
 | 
				
			||||||
          delete leavingVNodesCache[key]
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      leavingVNodesCache[key] = vnode
 | 
					      setLeavingNodeCache()
 | 
				
			||||||
      if (onLeave) {
 | 
					      if (onLeave) {
 | 
				
			||||||
        callAsyncHook(onLeave, [el, done])
 | 
					        callAsyncHook(onLeave, [el, done])
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
| 
						 | 
					@ -467,16 +512,8 @@ export function resolveTransitionHooks(
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    clone(vnode) {
 | 
					    clone(node) {
 | 
				
			||||||
      const hooks = resolveTransitionHooks(
 | 
					      return cloneHooks(node)
 | 
				
			||||||
        vnode,
 | 
					 | 
				
			||||||
        props,
 | 
					 | 
				
			||||||
        state,
 | 
					 | 
				
			||||||
        instance,
 | 
					 | 
				
			||||||
        postClone,
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
      if (postClone) postClone(hooks)
 | 
					 | 
				
			||||||
      return hooks
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,8 +150,10 @@ export { registerRuntimeCompiler, isRuntimeOnly } from './component'
 | 
				
			||||||
export {
 | 
					export {
 | 
				
			||||||
  useTransitionState,
 | 
					  useTransitionState,
 | 
				
			||||||
  resolveTransitionHooks,
 | 
					  resolveTransitionHooks,
 | 
				
			||||||
 | 
					  baseResolveTransitionHooks,
 | 
				
			||||||
  setTransitionHooks,
 | 
					  setTransitionHooks,
 | 
				
			||||||
  getTransitionRawChildren,
 | 
					  getTransitionRawChildren,
 | 
				
			||||||
 | 
					  leaveCbKey,
 | 
				
			||||||
} from './components/BaseTransition'
 | 
					} from './components/BaseTransition'
 | 
				
			||||||
export { initCustomFormatter } from './customFormatter'
 | 
					export { initCustomFormatter } from './customFormatter'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -335,6 +337,8 @@ export type { SuspenseBoundary } from './components/Suspense'
 | 
				
			||||||
export type {
 | 
					export type {
 | 
				
			||||||
  TransitionState,
 | 
					  TransitionState,
 | 
				
			||||||
  TransitionHooks,
 | 
					  TransitionHooks,
 | 
				
			||||||
 | 
					  TransitionHooksContext,
 | 
				
			||||||
 | 
					  TransitionElement,
 | 
				
			||||||
} from './components/BaseTransition'
 | 
					} from './components/BaseTransition'
 | 
				
			||||||
export type {
 | 
					export type {
 | 
				
			||||||
  AsyncComponentOptions,
 | 
					  AsyncComponentOptions,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,15 @@
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					  type GenericComponentInstance,
 | 
				
			||||||
 | 
					  type TransitionElement,
 | 
				
			||||||
  type TransitionHooks,
 | 
					  type TransitionHooks,
 | 
				
			||||||
 | 
					  type TransitionHooksContext,
 | 
				
			||||||
  type TransitionProps,
 | 
					  type TransitionProps,
 | 
				
			||||||
 | 
					  type TransitionState,
 | 
				
			||||||
  type VaporTransitionInterface,
 | 
					  type VaporTransitionInterface,
 | 
				
			||||||
 | 
					  baseResolveTransitionHooks,
 | 
				
			||||||
  currentInstance,
 | 
					  currentInstance,
 | 
				
			||||||
 | 
					  leaveCbKey,
 | 
				
			||||||
  registerVaporTransition,
 | 
					  registerVaporTransition,
 | 
				
			||||||
  resolveTransitionHooks,
 | 
					 | 
				
			||||||
  useTransitionState,
 | 
					  useTransitionState,
 | 
				
			||||||
} from '@vue/runtime-dom'
 | 
					} from '@vue/runtime-dom'
 | 
				
			||||||
import type { Block } from '../block'
 | 
					import type { Block } from '../block'
 | 
				
			||||||
| 
						 | 
					@ -64,6 +69,59 @@ export const vaporTransitionImpl: VaporTransitionInterface = {
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function resolveTransitionHooks(
 | 
				
			||||||
 | 
					  block: Block & { key: string },
 | 
				
			||||||
 | 
					  props: TransitionProps,
 | 
				
			||||||
 | 
					  state: TransitionState,
 | 
				
			||||||
 | 
					  instance: GenericComponentInstance,
 | 
				
			||||||
 | 
					  postClone?: (hooks: TransitionHooks) => void,
 | 
				
			||||||
 | 
					): TransitionHooks {
 | 
				
			||||||
 | 
					  const key = String(block.key)
 | 
				
			||||||
 | 
					  const leavingNodeCache = getLeavingNodesForBlock(state, block)
 | 
				
			||||||
 | 
					  const context: TransitionHooksContext = {
 | 
				
			||||||
 | 
					    setLeavingNodeCache: () => {
 | 
				
			||||||
 | 
					      leavingNodeCache[key] = block
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    unsetLeavingNodeCache: () => {
 | 
				
			||||||
 | 
					      if (leavingNodeCache[key] === block) {
 | 
				
			||||||
 | 
					        delete leavingNodeCache[key]
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    earlyRemove: () => {
 | 
				
			||||||
 | 
					      const leavingNode = leavingNodeCache[key]
 | 
				
			||||||
 | 
					      if (leavingNode && (leavingNode as TransitionElement)[leaveCbKey]) {
 | 
				
			||||||
 | 
					        // force early removal (not cancelled)
 | 
				
			||||||
 | 
					        ;(leavingNode as TransitionElement)[leaveCbKey]!()
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    cloneHooks: block => {
 | 
				
			||||||
 | 
					      const hooks = resolveTransitionHooks(
 | 
				
			||||||
 | 
					        block,
 | 
				
			||||||
 | 
					        props,
 | 
				
			||||||
 | 
					        state,
 | 
				
			||||||
 | 
					        instance,
 | 
				
			||||||
 | 
					        postClone,
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      if (postClone) postClone(hooks)
 | 
				
			||||||
 | 
					      return hooks
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return baseResolveTransitionHooks(context, props, state, instance)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getLeavingNodesForBlock(
 | 
				
			||||||
 | 
					  state: TransitionState,
 | 
				
			||||||
 | 
					  block: Block,
 | 
				
			||||||
 | 
					): Record<string, Block> {
 | 
				
			||||||
 | 
					  const { leavingVNodes } = state
 | 
				
			||||||
 | 
					  let leavingNodesCache = leavingVNodes.get(block)!
 | 
				
			||||||
 | 
					  if (!leavingNodesCache) {
 | 
				
			||||||
 | 
					    leavingNodesCache = Object.create(null)
 | 
				
			||||||
 | 
					    leavingVNodes.set(block, leavingNodesCache)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return leavingNodesCache
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function setTransitionHooks(block: Block, hooks: TransitionHooks) {
 | 
					function setTransitionHooks(block: Block, hooks: TransitionHooks) {
 | 
				
			||||||
  if (isVaporComponent(block)) {
 | 
					  if (isVaporComponent(block)) {
 | 
				
			||||||
    setTransitionHooks(block.block, hooks)
 | 
					    setTransitionHooks(block.block, hooks)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue