File tree Expand file tree Collapse file tree 4 files changed +39
-6
lines changed Expand file tree Collapse file tree 4 files changed +39
-6
lines changed Original file line number Diff line number Diff line change @@ -26,7 +26,27 @@ describe('vdomInterop', () => {
26
26
} )
27
27
} )
28
28
29
- describe . todo ( 'emit' , ( ) => { } )
29
+ describe ( 'emit' , ( ) => {
30
+ test ( 'emit from vapor child to vdom parent' , ( ) => {
31
+ const VaporChild = defineVaporComponent ( {
32
+ emits : [ 'click' ] ,
33
+ setup ( _ , { emit } ) {
34
+ emit ( 'click' )
35
+ return [ ]
36
+ } ,
37
+ } )
38
+
39
+ const fn = vi . fn ( )
40
+ define ( {
41
+ setup ( ) {
42
+ return ( ) => h ( VaporChild as any , { onClick : fn } )
43
+ } ,
44
+ } ) . render ( )
45
+
46
+ // fn should be called once
47
+ expect ( fn ) . toHaveBeenCalledTimes ( 1 )
48
+ } )
49
+ } )
30
50
31
51
describe ( 'slots' , ( ) => {
32
52
test ( 'basic' , ( ) => {
Original file line number Diff line number Diff line change 1
1
import { type ObjectEmitsOptions , baseEmit } from '@vue/runtime-dom'
2
2
import type { VaporComponent , VaporComponentInstance } from './component'
3
3
import { EMPTY_OBJ , hasOwn , isArray } from '@vue/shared'
4
- import { resolveSource } from './componentProps'
4
+ import { type RawProps , resolveSource } from './componentProps'
5
+ import { interopKey } from './vdomInterop'
5
6
6
7
/**
7
8
* The logic from core isn't too reusable so it's better to duplicate here
@@ -40,13 +41,17 @@ export function emit(
40
41
)
41
42
}
42
43
43
- function propGetter ( rawProps : Record < string , any > , key : string ) {
44
+ function propGetter ( rawProps : RawProps , key : string ) {
44
45
const dynamicSources = rawProps . $
45
46
if ( dynamicSources ) {
46
47
let i = dynamicSources . length
47
48
while ( i -- ) {
48
49
const source = resolveSource ( dynamicSources [ i ] )
49
- if ( hasOwn ( source , key ) ) return resolveSource ( source [ key ] )
50
+ if ( hasOwn ( source , key ) )
51
+ // for props passed from VDOM component, no need to resolve
52
+ return dynamicSources [ interopKey ]
53
+ ? source [ key ]
54
+ : resolveSource ( source [ key ] )
50
55
}
51
56
}
52
57
return rawProps [ key ] && resolveSource ( rawProps [ key ] )
Original file line number Diff line number Diff line change @@ -23,10 +23,11 @@ import {
23
23
import { ReactiveFlags } from '@vue/reactivity'
24
24
import { normalizeEmitsOptions } from './componentEmits'
25
25
import { renderEffect } from './renderEffect'
26
+ import type { interopKey } from './vdomInterop'
26
27
27
28
export type RawProps = Record < string , ( ) => unknown > & {
28
29
// generated by compiler for :[key]="x" or v-bind="x"
29
- $ ?: DynamicPropsSource [ ]
30
+ $ ?: DynamicPropsSource [ ] & { [ interopKey ] ?: boolean }
30
31
}
31
32
32
33
export type DynamicPropsSource =
Original file line number Diff line number Diff line change @@ -37,6 +37,8 @@ import { renderEffect } from './renderEffect'
37
37
import { createTextNode } from './dom/node'
38
38
import { optimizePropertyLookup } from './dom/prop'
39
39
40
+ export const interopKey : unique symbol = Symbol ( `interop` )
41
+
40
42
// mounting vapor components and slots in vdom
41
43
const vaporInteropImpl : Omit <
42
44
VaporInteropInterface ,
@@ -51,11 +53,16 @@ const vaporInteropImpl: Omit<
51
53
const propsRef = shallowRef ( vnode . props )
52
54
const slotsRef = shallowRef ( vnode . children )
53
55
56
+ const dynamicPropSource : ( ( ) => any ) [ ] & { [ interopKey ] ?: boolean } = [
57
+ ( ) => propsRef . value ,
58
+ ]
59
+ // mark as interop props
60
+ dynamicPropSource [ interopKey ] = true
54
61
// @ts -expect-error
55
62
const instance = ( vnode . component = createComponent (
56
63
vnode . type as any as VaporComponent ,
57
64
{
58
- $ : [ ( ) => propsRef . value ] ,
65
+ $ : dynamicPropSource ,
59
66
} as RawProps ,
60
67
{
61
68
_ : slotsRef , // pass the slots ref
You can’t perform that action at this time.
0 commit comments