fix(vapor): component emits vdom interop

This commit is contained in:
daiwei 2025-06-19 16:52:37 +08:00
parent 88ef97ffd3
commit 26dbd3c902
4 changed files with 39 additions and 4 deletions

View File

@ -4,12 +4,18 @@
// ./rendererAttrsFallthrough.spec.ts. // ./rendererAttrsFallthrough.spec.ts.
import { import {
createApp,
h,
isEmitListener, isEmitListener,
nextTick, nextTick,
onBeforeUnmount, onBeforeUnmount,
toHandlers, toHandlers,
} from '@vue/runtime-dom' } from '@vue/runtime-dom'
import { createComponent, defineVaporComponent } from '../src' import {
createComponent,
defineVaporComponent,
vaporInteropPlugin,
} from '../src'
import { makeRender } from './_utils' import { makeRender } from './_utils'
const define = makeRender() const define = makeRender()
@ -425,3 +431,28 @@ describe('component: emit', () => {
expect(fn).not.toHaveBeenCalled() expect(fn).not.toHaveBeenCalled()
}) })
}) })
describe('vdom interop', () => {
test('vdom parent > vapor child', () => {
const VaporChild = defineVaporComponent({
emits: ['click'],
setup(_, { emit }) {
emit('click')
return []
},
})
const fn = vi.fn()
const App = {
setup() {
return () => h(VaporChild as any, { onClick: fn })
},
}
const root = document.createElement('div')
createApp(App).use(vaporInteropPlugin).mount(root)
// fn should be called once
expect(fn).toHaveBeenCalledTimes(1)
})
})

View File

@ -46,7 +46,11 @@ function propGetter(rawProps: Record<string, any>, key: string) {
let i = dynamicSources.length let i = dynamicSources.length
while (i--) { while (i--) {
const source = resolveSource(dynamicSources[i]) const source = resolveSource(dynamicSources[i])
if (hasOwn(source, key)) return resolveSource(source[key]) if (hasOwn(source, key))
// for props passed from VDOM component, no need to resolve
return dynamicSources.__interop
? source[key]
: resolveSource(source[key])
} }
} }
return rawProps[key] && resolveSource(rawProps[key]) return rawProps[key] && resolveSource(rawProps[key])

View File

@ -26,7 +26,7 @@ import { renderEffect } from './renderEffect'
export type RawProps = Record<string, () => unknown> & { export type RawProps = Record<string, () => unknown> & {
// generated by compiler for :[key]="x" or v-bind="x" // generated by compiler for :[key]="x" or v-bind="x"
$?: DynamicPropsSource[] $?: DynamicPropsSource[] & { __interop?: boolean }
} }
export type DynamicPropsSource = export type DynamicPropsSource =

View File

@ -52,7 +52,7 @@ const vaporInteropImpl: Omit<
const instance = (vnode.component = createComponent( const instance = (vnode.component = createComponent(
vnode.type as any as VaporComponent, vnode.type as any as VaporComponent,
{ {
$: [() => propsRef.value], $: extend([() => propsRef.value], { __interop: true }),
} as RawProps, } as RawProps,
{ {
_: slotsRef, // pass the slots ref _: slotsRef, // pass the slots ref