]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: refactor
authordaiwei <daiwei521@126.com>
Wed, 5 Mar 2025 00:27:57 +0000 (08:27 +0800)
committerdaiwei <daiwei521@126.com>
Wed, 5 Mar 2025 00:27:57 +0000 (08:27 +0800)
packages/runtime-vapor/src/block.ts
packages/runtime-vapor/src/components/Transition.ts
packages/runtime-vapor/src/directives/vShow.ts
packages/runtime-vapor/src/dom/prop.ts

index 96c4d94d4233a066d6cc751868823b69f5c82fc2..6dbc05d2195df0cb076b0538b831168545af8fe5 100644 (file)
@@ -35,7 +35,7 @@ export interface VaporTransitionHooks extends TransitionHooks {
 
 export type TransitionBlock = {
   key?: any
-  transition?: VaporTransitionHooks
+  $transition?: VaporTransitionHooks
 }
 
 export type BlockFn = (...args: any[]) => Block
@@ -45,7 +45,7 @@ export class VaporFragment {
   anchor?: Node
   insert?: (parent: ParentNode, anchor: Node | null) => void
   remove?: (parent?: ParentNode) => void
-  transitionChild?: TransitionBlock | undefined
+  $transition?: VaporTransitionHooks | undefined
 
   constructor(nodes: Block) {
     this.nodes = nodes
@@ -57,7 +57,6 @@ export class DynamicFragment extends VaporFragment {
   scope: EffectScope | undefined
   current?: BlockFn
   fallback?: BlockFn
-  transitionChild?: Block
 
   constructor(anchorLabel?: string) {
     super([])
@@ -74,16 +73,13 @@ export class DynamicFragment extends VaporFragment {
     pauseTracking()
     const parent = this.anchor.parentNode
 
-    const transition = this.transition
+    const transition = this.$transition
     const renderBranch = () => {
       if (render) {
         this.scope = new EffectScope()
         this.nodes = this.scope.run(render) || []
         if (transition) {
-          this.transitionChild = applyTransitionEnterHooks(
-            this.nodes,
-            transition,
-          )
+          this.$transition = applyTransitionEnterHooks(this.nodes, transition)
         }
         if (parent) insert(this.nodes, parent, this.anchor)
       } else {
@@ -120,10 +116,6 @@ export class DynamicFragment extends VaporFragment {
 
     resetTracking()
   }
-
-  get transition(): VaporTransitionHooks | undefined {
-    return this.transitionChild && this.transitionChild.transition
-  }
 }
 
 export function isFragment(val: NonNullable<unknown>): val is VaporFragment {
@@ -161,11 +153,11 @@ export function insert(
   anchor = anchor === 0 ? parent.firstChild : anchor
   if (block instanceof Node) {
     // don't apply transition on text or comment nodes
-    if (block.transition && block instanceof Element) {
+    if (block.$transition && block instanceof Element) {
       performTransitionEnter(
         block,
         // @ts-expect-error
-        block.transition,
+        block.$transition,
         () => parent.insertBefore(block, anchor),
         parentSuspense,
       )
@@ -196,11 +188,11 @@ export function prepend(parent: ParentNode, ...blocks: Block[]): void {
 
 export function remove(block: Block, parent?: ParentNode): void {
   if (block instanceof Node) {
-    if (block.transition && block instanceof Element) {
+    if (block.$transition && block instanceof Element) {
       performTransitionLeave(
         block,
         // @ts-expect-error
-        block.transition,
+        block.$transition,
         () => parent && parent.removeChild(block),
       )
     } else {
index 210c0855ef6f1db52b864a3c8fe3f580204597ee..8a705fda0290de4721285cfbb490585fd86e40d6 100644 (file)
@@ -111,18 +111,19 @@ function resolveTransitionHooks(
 
 function setTransitionHooks(block: Block, hooks: VaporTransitionHooks) {
   if (!isFragment(block)) {
-    block.transition = hooks
+    block.$transition = hooks
   }
 }
 
 export function applyTransitionEnterHooks(
   block: Block,
   hooks: VaporTransitionHooks,
-): Block | undefined {
+): VaporTransitionHooks | undefined {
   const child = findElementChild(block)
+  let enterHooks
   if (child) {
     const { props, state, delayedLeave } = hooks
-    let enterHooks = resolveTransitionHooks(
+    enterHooks = resolveTransitionHooks(
       child,
       props,
       state,
@@ -132,10 +133,10 @@ export function applyTransitionEnterHooks(
     enterHooks.delayedLeave = delayedLeave
     setTransitionHooks(child, enterHooks)
     if (isFragment(block)) {
-      block.transitionChild = child
+      block.$transition = enterHooks
     }
   }
-  return child
+  return enterHooks
 }
 
 export function applyTransitionLeaveHooks(
@@ -161,6 +162,7 @@ export function applyTransitionLeaveHooks(
     leavingHooks.afterLeave = () => {
       state.isLeaving = false
       afterLeaveCb()
+      leavingBlock.$transition = undefined
       delete leavingHooks.afterLeave
     }
   } else if (mode === 'in-out') {
@@ -174,17 +176,24 @@ export function applyTransitionLeaveHooks(
       block[leaveCbKey] = () => {
         earlyRemove()
         block[leaveCbKey] = undefined
+        leavingBlock.$transition = undefined
         delete enterHooks.delayedLeave
       }
       enterHooks.delayedLeave = () => {
         delayedLeave()
+        leavingBlock.$transition = undefined
         delete enterHooks.delayedLeave
       }
     }
   }
 }
 
+const transitionChildCache = new WeakMap<Block, Block>()
 export function findElementChild(block: Block): Block | undefined {
+  if (transitionChildCache.has(block)) {
+    return transitionChildCache.get(block)
+  }
+
   let child: Block | undefined
   if (block instanceof Node) {
     // transition can only be applied on Element child
index 492d5225ef25306b3f5590886b0a6ce6a2313889..82855fef847b2165873030f51cdce7824fbe513b 100644 (file)
@@ -39,20 +39,20 @@ function setDisplay(target: Block, value: unknown): void {
   if (target instanceof DynamicFragment) {
     return setDisplay(target.nodes, value)
   }
-  const { transition } = target
+  const { $transition } = target
   if (target instanceof Element) {
     const el = target as VShowElement
     if (!(vShowOriginalDisplay in el)) {
       el[vShowOriginalDisplay] =
         el.style.display === 'none' ? '' : el.style.display
     }
-    if (transition) {
+    if ($transition) {
       if (value) {
-        transition.beforeEnter(target)
+        $transition.beforeEnter(target)
         el.style.display = el[vShowOriginalDisplay]!
-        transition.enter(target)
+        $transition.enter(target)
       } else {
-        transition.leave(target, () => {
+        $transition.leave(target, () => {
           el.style.display = 'none'
         })
       }
index f464a2f6299e56e87593aea0ba867dddd9dd2a49..377d67c934981d274b62e0832871c23803a926b2 100644 (file)
@@ -267,6 +267,7 @@ export function optimizePropertyLookup(): void {
   if (isOptimized) return
   isOptimized = true
   const proto = Element.prototype as any
+  proto.$transition = undefined
   proto.$evtclick = undefined
   proto.$root = false
   proto.$html =