wip: handle fallthrough attrs

This commit is contained in:
daiwei 2025-03-13 21:46:40 +08:00
parent c9ee8d1eac
commit ecef92b1dc
2 changed files with 42 additions and 18 deletions

View File

@ -22,7 +22,7 @@ import {
isFragment, isFragment,
} from '../block' } from '../block'
import { type VaporComponentInstance, isVaporComponent } from '../component' import { type VaporComponentInstance, isVaporComponent } from '../component'
import { isArray } from '@vue/shared' import { extend, isArray } from '@vue/shared'
import { renderEffect } from '../renderEffect' import { renderEffect } from '../renderEffect'
import { setDynamicProps } from '../dom/prop' import { setDynamicProps } from '../dom/prop'
@ -34,10 +34,11 @@ const decorate = (t: typeof VaporTransition) => {
} }
export const VaporTransition: FunctionalComponent<TransitionProps> = export const VaporTransition: FunctionalComponent<TransitionProps> =
/*@__PURE__*/ decorate((props, { slots }) => { /*@__PURE__*/ decorate((props, { slots, attrs }) => {
const children = (slots.default && slots.default()) as any as Block const children = (slots.default && slots.default()) as any as Block
if (!children) return if (!children) return
const instance = currentInstance! as VaporComponentInstance
const { mode } = props const { mode } = props
checkTransitionMode(mode) checkTransitionMode(mode)
@ -48,15 +49,13 @@ export const VaporTransition: FunctionalComponent<TransitionProps> =
if (isMounted) { if (isMounted) {
// only update props for Fragment block, for later reusing // only update props for Fragment block, for later reusing
if (isFragment(children)) { if (isFragment(children)) {
if (children.$transition) { children.$transition!.props = resolvedProps
children.$transition.props = resolvedProps
}
} else { } else {
// replace existing transition hooks
const child = findTransitionBlock(children) const child = findTransitionBlock(children)
if (child && child.$transition) { if (child) {
child.$transition.props = resolvedProps // replace existing transition hooks
applyTransitionHooks(child, child.$transition) child.$transition!.props = resolvedProps
applyTransitionHooks(child, child.$transition!)
} }
} }
} else { } else {
@ -64,11 +63,31 @@ export const VaporTransition: FunctionalComponent<TransitionProps> =
} }
}) })
applyTransitionHooks(children, { // fallthrough attrs
state: useTransitionState(), let fallthroughAttrs = true
props: resolvedProps!, if (instance.hasFallthrough) {
instance: currentInstance!, renderEffect(() => {
} as VaporTransitionHooks) // 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 return children
}) })
@ -164,7 +183,6 @@ export function applyTransitionHooks(
setTransitionHooks(child, resolvedHooks) setTransitionHooks(child, resolvedHooks)
if (isFrag) setTransitionHooksToFragment(block, resolvedHooks) if (isFrag) setTransitionHooksToFragment(block, resolvedHooks)
// TODO handle attrs update
// fallthrough attrs // fallthrough attrs
if (fallthroughAttrs && instance.hasFallthrough) { if (fallthroughAttrs && instance.hasFallthrough) {
setDynamicProps(child, [instance.attrs]) setDynamicProps(child, [instance.attrs])

View File

@ -28,7 +28,11 @@ import {
setTransitionHooks, setTransitionHooks,
setTransitionHooksToFragment, setTransitionHooksToFragment,
} from './Transition' } from './Transition'
import { type ObjectVaporComponent, isVaporComponent } from '../component' import {
type ObjectVaporComponent,
type VaporComponentInstance,
isVaporComponent,
} from '../component'
import { isForBlock } from '../apiCreateFor' import { isForBlock } from '../apiCreateFor'
import { renderEffect, setDynamicProps } from '@vue/runtime-vapor' import { renderEffect, setDynamicProps } from '@vue/runtime-vapor'
@ -50,7 +54,7 @@ export const VaporTransitionGroup: ObjectVaporComponent = decorate({
}), }),
setup(props: TransitionGroupProps, { slots }) { setup(props: TransitionGroupProps, { slots }) {
const instance = currentInstance const instance = currentInstance as VaporComponentInstance
const state = useTransitionState() const state = useTransitionState()
const cssTransitionProps = resolveTransitionProps(props) const cssTransitionProps = resolveTransitionProps(props)
@ -144,7 +148,9 @@ export const VaporTransitionGroup: ObjectVaporComponent = decorate({
const container = document.createElement(tag) const container = document.createElement(tag)
insert(slottedBlock, container) insert(slottedBlock, container)
// fallthrough attrs // fallthrough attrs
renderEffect(() => setDynamicProps(container, [instance!.attrs])) if (instance!.hasFallthrough) {
renderEffect(() => setDynamicProps(container, [instance!.attrs]))
}
return container return container
} else { } else {
const frag = __DEV__ const frag = __DEV__