]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: handle fallthrough attrs
authordaiwei <daiwei521@126.com>
Thu, 13 Mar 2025 13:46:40 +0000 (21:46 +0800)
committerdaiwei <daiwei521@126.com>
Fri, 14 Mar 2025 02:42:21 +0000 (10:42 +0800)
packages/runtime-vapor/src/components/Transition.ts
packages/runtime-vapor/src/components/TransitionGroup.ts

index 03f8a003e6a4e80183b4a0c7a2cdec5c7d21a4e6..7f6179a3a7a1406d43490b86c54af94f1c75b7d6 100644 (file)
@@ -22,7 +22,7 @@ import {
   isFragment,
 } from '../block'
 import { type VaporComponentInstance, isVaporComponent } from '../component'
-import { isArray } from '@vue/shared'
+import { extend, isArray } from '@vue/shared'
 import { renderEffect } from '../renderEffect'
 import { setDynamicProps } from '../dom/prop'
 
@@ -34,10 +34,11 @@ const decorate = (t: typeof VaporTransition) => {
 }
 
 export const VaporTransition: FunctionalComponent<TransitionProps> =
-  /*@__PURE__*/ decorate((props, { slots }) => {
+  /*@__PURE__*/ decorate((props, { slots, attrs }) => {
     const children = (slots.default && slots.default()) as any as Block
     if (!children) return
 
+    const instance = currentInstance! as VaporComponentInstance
     const { mode } = props
     checkTransitionMode(mode)
 
@@ -48,15 +49,13 @@ export const VaporTransition: FunctionalComponent<TransitionProps> =
       if (isMounted) {
         // only update props for Fragment block, for later reusing
         if (isFragment(children)) {
-          if (children.$transition) {
-            children.$transition.props = resolvedProps
-          }
+          children.$transition!.props = resolvedProps
         } else {
-          // replace existing transition hooks
           const child = findTransitionBlock(children)
-          if (child && child.$transition) {
-            child.$transition.props = resolvedProps
-            applyTransitionHooks(child, child.$transition)
+          if (child) {
+            // replace existing transition hooks
+            child.$transition!.props = resolvedProps
+            applyTransitionHooks(child, child.$transition!)
           }
         }
       } else {
@@ -64,11 +63,31 @@ export const VaporTransition: FunctionalComponent<TransitionProps> =
       }
     })
 
-    applyTransitionHooks(children, {
-      state: useTransitionState(),
-      props: resolvedProps!,
-      instance: currentInstance!,
-    } as VaporTransitionHooks)
+    // fallthrough attrs
+    let fallthroughAttrs = true
+    if (instance.hasFallthrough) {
+      renderEffect(() => {
+        // attrs are accessed in advance
+        const resolvedAttrs = extend({}, attrs)
+        const child = findTransitionBlock(children)
+        if (child) {
+          setDynamicProps(child, [resolvedAttrs])
+          // ensure fallthrough attrs are not happened again in
+          // applyTransitionHooks
+          fallthroughAttrs = false
+        }
+      })
+    }
+
+    applyTransitionHooks(
+      children,
+      {
+        state: useTransitionState(),
+        props: resolvedProps!,
+        instance: instance,
+      } as VaporTransitionHooks,
+      fallthroughAttrs,
+    )
 
     return children
   })
@@ -164,7 +183,6 @@ export function applyTransitionHooks(
   setTransitionHooks(child, resolvedHooks)
   if (isFrag) setTransitionHooksToFragment(block, resolvedHooks)
 
-  // TODO handle attrs update
   // fallthrough attrs
   if (fallthroughAttrs && instance.hasFallthrough) {
     setDynamicProps(child, [instance.attrs])
index a811505f56d9168ed40bcc3e62c29dc1325fb628..c12260bf37b9097d7ada7aaad889525cd36782ea 100644 (file)
@@ -28,7 +28,11 @@ import {
   setTransitionHooks,
   setTransitionHooksToFragment,
 } from './Transition'
-import { type ObjectVaporComponent, isVaporComponent } from '../component'
+import {
+  type ObjectVaporComponent,
+  type VaporComponentInstance,
+  isVaporComponent,
+} from '../component'
 import { isForBlock } from '../apiCreateFor'
 import { renderEffect, setDynamicProps } from '@vue/runtime-vapor'
 
@@ -50,7 +54,7 @@ export const VaporTransitionGroup: ObjectVaporComponent = decorate({
   }),
 
   setup(props: TransitionGroupProps, { slots }) {
-    const instance = currentInstance
+    const instance = currentInstance as VaporComponentInstance
     const state = useTransitionState()
     const cssTransitionProps = resolveTransitionProps(props)
 
@@ -144,7 +148,9 @@ export const VaporTransitionGroup: ObjectVaporComponent = decorate({
       const container = document.createElement(tag)
       insert(slottedBlock, container)
       // fallthrough attrs
-      renderEffect(() => setDynamicProps(container, [instance!.attrs]))
+      if (instance!.hasFallthrough) {
+        renderEffect(() => setDynamicProps(container, [instance!.attrs]))
+      }
       return container
     } else {
       const frag = __DEV__