]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: inject useVaporTransition call for treeshaking
authordaiwei <daiwei521@126.com>
Wed, 5 Mar 2025 02:12:19 +0000 (10:12 +0800)
committerdaiwei <daiwei521@126.com>
Wed, 5 Mar 2025 02:12:19 +0000 (10:12 +0800)
packages/compiler-vapor/src/generate.ts
packages/compiler-vapor/src/ir/index.ts
packages/compiler-vapor/src/transform.ts
packages/compiler-vapor/src/transforms/vIf.ts
packages/compiler-vapor/src/transforms/vSlot.ts
packages/runtime-vapor/src/apiCreateApp.ts
packages/runtime-vapor/src/components/Transition.ts
packages/runtime-vapor/src/index.ts
packages/runtime-vapor/src/vdomInterop.ts

index 193a0f5da777be3f443ac9aa2480870aad6a3d34..64d346d1d59733a9473c800c6369d974ea3fe7a7 100644 (file)
@@ -129,6 +129,11 @@ export function generate(
       `const ${setTemplateRefIdent} = ${context.helper('createTemplateRefSetter')}()`,
     )
   }
+
+  if (ir.hasTransition) {
+    push(NEWLINE, `${context.helper('useVaporTransition')}()`)
+  }
+
   push(...genBlockContent(ir.block, context, true))
   push(INDENT_END, NEWLINE)
 
index 71e896e13f19d527e7cf129f42c5b79a057043b9..6c80662a57dcad510b8b9e2e77552b26ba508e44 100644 (file)
@@ -68,6 +68,7 @@ export interface RootIRNode {
   directive: Set<string>
   block: BlockIRNode
   hasTemplateRef: boolean
+  hasTransition: boolean
 }
 
 export interface IfIRNode extends BaseIRNode {
index 76563899d2b770b19aae215805cded9c13ba85b5..788b1889ab9d259f84f530a624b50c87c97ea4e0 100644 (file)
@@ -230,6 +230,7 @@ export function transform(
     directive: new Set(),
     block: newBlock(node),
     hasTemplateRef: false,
+    hasTransition: false,
   }
 
   const context = new TransformContext(ir, node, options)
index 5306cf70573d3f7f9775cc2c2041bc75a8022d8b..91513434957ad7a53ed05b67d996eebfb2dfdf17 100644 (file)
@@ -134,12 +134,20 @@ export function isInTransition(
   context: TransformContext<ElementNode>,
 ): boolean {
   const parentNode = context.parent && context.parent.node
-  return !!(parentNode && isTransitionNode(parentNode as ElementNode))
+  return !!(parentNode && isTransitionNode(parentNode as ElementNode, context))
 }
 
-export function isTransitionNode(node: ElementNode): boolean {
-  return (
+export function isTransitionNode(
+  node: ElementNode,
+  context: TransformContext<ElementNode>,
+): boolean {
+  const inTransition =
     node.type === NodeTypes.ELEMENT &&
     (node.tag === 'transition' || node.tag === 'Transition')
-  )
+
+  if (inTransition) {
+    context.ir.hasTransition = true
+  }
+
+  return inTransition
 }
index c1b82e2bc576a03843203e0e6f5ccdef94f93858..d14f91b58c47e83766cf443373510eeccf732d24 100644 (file)
@@ -74,7 +74,7 @@ function transformComponentSlot(
   )
 
   let slotKey
-  if (isTransitionNode(node)) {
+  if (isTransitionNode(node, context)) {
     const keyProp = findProp(
       nonSlotTemplateChildren[0] as ElementNode,
       'key',
index da09a79a12a737f99c8bb7edacfec672756b08c3..8088e1aee6d49f4cae7989723575242e9027867d 100644 (file)
@@ -20,13 +20,11 @@ import {
 import type { RawProps } from './componentProps'
 import { getGlobalThis } from '@vue/shared'
 import { optimizePropertyLookup } from './dom/prop'
-import { ensureVaporTransition } from './components/Transition'
 
 let _createApp: CreateAppFunction<ParentNode, VaporComponent>
 
 const mountApp: AppMountFn<ParentNode> = (app, container) => {
   optimizePropertyLookup()
-  ensureVaporTransition()
 
   // clear content before mounting
   if (container.nodeType === 1 /* Node.ELEMENT_NODE */) {
index 44f87023edc75ae126df41901b841adb2702e477..a7f540fa6aec912da3eabbe5952de6c0b75ff484 100644 (file)
@@ -21,6 +21,7 @@ import {
 } from '../block'
 import { isVaporComponent } from '../component'
 
+/*#__NO_SIDE_EFFECTS__*/
 export const vaporTransitionImpl: VaporTransitionInterface = {
   applyTransition: (
     props: TransitionProps,
@@ -118,31 +119,29 @@ function setTransitionHooks(
   block: TransitionBlock,
   hooks: VaporTransitionHooks,
 ) {
-  if (!isFragment(block)) {
-    block.$transition = hooks
-  }
+  block.$transition = hooks
 }
 
 export function applyTransitionEnterHooks(
   block: Block,
   hooks: VaporTransitionHooks,
-): VaporTransitionHooks | undefined {
-  const child = findElementChild(block)
-  let enterHooks
-  if (child) {
-    const { props, state, delayedLeave } = hooks
-    enterHooks = resolveTransitionHooks(
-      child,
-      props,
-      state,
-      currentInstance!,
-      hooks => (enterHooks = hooks as VaporTransitionHooks),
-    )
-    enterHooks.delayedLeave = delayedLeave
-    setTransitionHooks(child, enterHooks)
-    if (isFragment(block)) {
-      block.$transition = enterHooks
-    }
+): VaporTransitionHooks {
+  const child = findTransitionBlock(block)
+  if (!child) return hooks
+
+  const { props, state, delayedLeave } = hooks
+  let enterHooks = resolveTransitionHooks(
+    child,
+    props,
+    state,
+    currentInstance!,
+    hooks => (enterHooks = hooks as VaporTransitionHooks),
+  )
+  enterHooks.delayedLeave = delayedLeave
+  setTransitionHooks(child, enterHooks)
+  if (isFragment(block)) {
+    // also set transition hooks on fragment for reusing during it's updating
+    setTransitionHooks(block, enterHooks)
   }
   return enterHooks
 }
@@ -152,7 +151,7 @@ export function applyTransitionLeaveHooks(
   enterHooks: VaporTransitionHooks,
   afterLeaveCb: () => void,
 ): void {
-  const leavingBlock = findElementChild(block)
+  const leavingBlock = findTransitionBlock(block)
   if (!leavingBlock) return undefined
 
   const { props, state } = enterHooks
@@ -196,10 +195,10 @@ export function applyTransitionLeaveHooks(
   }
 }
 
-const transitionChildCache = new WeakMap<Block, TransitionBlock>()
-export function findElementChild(block: Block): TransitionBlock | undefined {
-  if (transitionChildCache.has(block)) {
-    return transitionChildCache.get(block)
+const transitionBlockCache = new WeakMap<Block, TransitionBlock>()
+export function findTransitionBlock(block: Block): TransitionBlock | undefined {
+  if (transitionBlockCache.has(block)) {
+    return transitionBlockCache.get(block)
   }
 
   let child: TransitionBlock | undefined
@@ -207,12 +206,12 @@ export function findElementChild(block: Block): TransitionBlock | undefined {
     // transition can only be applied on Element child
     if (block instanceof Element) child = block
   } else if (isVaporComponent(block)) {
-    child = findElementChild(block.block)
+    child = findTransitionBlock(block.block)
   } else if (Array.isArray(block)) {
     child = block[0] as TransitionBlock
     let hasFound = false
     for (const c of block) {
-      const item = findElementChild(c)
+      const item = findTransitionBlock(c)
       if (item instanceof Element) {
         if (__DEV__ && hasFound) {
           // warn more than one non-comment child
@@ -228,7 +227,7 @@ export function findElementChild(block: Block): TransitionBlock | undefined {
       }
     }
   } else if (isFragment(block)) {
-    child = findElementChild(block.nodes)
+    child = findTransitionBlock(block.nodes)
   }
 
   if (__DEV__ && !child) {
@@ -239,7 +238,8 @@ export function findElementChild(block: Block): TransitionBlock | undefined {
 }
 
 let registered = false
-export function ensureVaporTransition(): void {
+/*#__NO_SIDE_EFFECTS__*/
+export function useVaporTransition(): void {
   if (!registered) {
     registerVaporTransition(vaporTransitionImpl)
     registered = true
index c356727f8625cb0fdeebeedaa03aca69b9e62627..4a9986b43ab9aede20df70a46e149acb51a9f068 100644 (file)
@@ -42,3 +42,4 @@ export {
   applyDynamicModel,
 } from './directives/vModel'
 export { withVaporDirectives } from './directives/custom'
+export { useVaporTransition } from './components/Transition'
index efe8223c6049f5133d1b4c7d756274a6a7637d11..77228fd72a02fe85a5496daf7d89bc37e197a4d2 100644 (file)
@@ -33,7 +33,6 @@ import type { RawSlots, VaporSlot } from './componentSlots'
 import { renderEffect } from './renderEffect'
 import { createTextNode } from './dom/node'
 import { optimizePropertyLookup } from './dom/prop'
-import { ensureVaporTransition } from './components/Transition'
 
 // mounting vapor components and slots in vdom
 const vaporInteropImpl: Omit<
@@ -289,7 +288,6 @@ export const vaporInteropPlugin: Plugin = app => {
   const mount = app.mount
   app.mount = ((...args) => {
     optimizePropertyLookup()
-    ensureVaporTransition()
     return mount(...args)
   }) satisfies App['mount']
 }