diff --git a/packages/runtime-vapor/__tests__/componentAttrs.spec.ts b/packages/runtime-vapor/__tests__/componentAttrs.spec.ts index 109b1aa2f..6fef2ba60 100644 --- a/packages/runtime-vapor/__tests__/componentAttrs.spec.ts +++ b/packages/runtime-vapor/__tests__/componentAttrs.spec.ts @@ -445,4 +445,33 @@ describe('attribute fallthrough', () => { // fn should be called once expect(fn).toHaveBeenCalledTimes(1) }) + + it('should fallthrough attrs to vdom child', () => { + const VDomChild = defineComponent({ + setup() { + return () => h('div') + }, + }) + + const VaporChild = defineVaporComponent({ + setup() { + return createComponent( + VDomChild as any, + { foo: () => 'vapor foo' }, + null, + true, + ) + }, + }) + + const App = { + setup() { + return () => h(VaporChild as any, { foo: 'foo', bar: 'bar' }) + }, + } + + const root = document.createElement('div') + createApp(App).use(vaporInteropPlugin).mount(root) + expect(root.innerHTML).toBe('
') + }) }) diff --git a/packages/runtime-vapor/__tests__/componentSlots.spec.ts b/packages/runtime-vapor/__tests__/componentSlots.spec.ts index 58076fff9..d6f4c0af3 100644 --- a/packages/runtime-vapor/__tests__/componentSlots.spec.ts +++ b/packages/runtime-vapor/__tests__/componentSlots.spec.ts @@ -241,14 +241,11 @@ describe('component: slots', () => { }), ).render() - expect(props).toEqual({ foo: 100, baz: 'qux' }) + // foo has higher priority than bindObj.foo + expect(props).toEqual({ foo: 0, baz: 'qux' }) foo.value = 2 await nextTick() - expect(props).toEqual({ foo: 100, baz: 'qux' }) - - delete bindObj.value.foo - await nextTick() expect(props).toEqual({ foo: 2, baz: 'qux' }) }) diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index af15133db..190dbc5fc 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -150,19 +150,6 @@ export function createComponent( resetInsertionState() } - // vdom interop enabled and component is not an explicit vapor component - if (appContext.vapor && !component.__vapor) { - const frag = appContext.vapor.vdomMount( - component as any, - rawProps, - rawSlots, - ) - if (!isHydrating && _insertionParent) { - insert(frag, _insertionParent, _insertionAnchor) - } - return frag - } - if ( isSingleRoot && component.inheritAttrs !== false && @@ -181,6 +168,19 @@ export function createComponent( } } + // vdom interop enabled and component is not an explicit vapor component + if (appContext.vapor && !component.__vapor) { + const frag = appContext.vapor.vdomMount( + component as any, + rawProps, + rawSlots, + ) + if (!isHydrating && _insertionParent) { + insert(frag, _insertionParent, _insertionAnchor) + } + return frag + } + const instance = new VaporComponentInstance( component, rawProps as RawProps, diff --git a/packages/runtime-vapor/src/componentProps.ts b/packages/runtime-vapor/src/componentProps.ts index 9cf65c571..a8fbafd5f 100644 --- a/packages/runtime-vapor/src/componentProps.ts +++ b/packages/runtime-vapor/src/componentProps.ts @@ -178,6 +178,16 @@ export function getAttrFromRawProps(rawProps: RawProps, key: string): unknown { if (key === '$') return // need special merging behavior for class & style const merged = key === 'class' || key === 'style' ? ([] as any[]) : undefined + + // rawProps has high priority + if (hasOwn(rawProps, key)) { + if (merged) { + merged.push(rawProps[key]()) + } else { + return rawProps[key]() + } + } + const dynamicSources = rawProps.$ if (dynamicSources) { let i = dynamicSources.length @@ -196,13 +206,7 @@ export function getAttrFromRawProps(rawProps: RawProps, key: string): unknown { } } } - if (hasOwn(rawProps, key)) { - if (merged) { - merged.push(rawProps[key]()) - } else { - return rawProps[key]() - } - } + if (merged && merged.length) { return merged }