Skip to content

Commit d5adf95

Browse files
authored
feat(runtime-vapor): support functional slot in vdom component (#13576)
1 parent 1611bb1 commit d5adf95

File tree

4 files changed

+66
-8
lines changed

4 files changed

+66
-8
lines changed

packages/runtime-core/src/helpers/renderSlot.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function renderSlot(
3535
let slot = slots[name]
3636

3737
// vapor slots rendered in vdom
38-
if (slot && slots._vapor) {
38+
if (slot && (slot as any).__vapor) {
3939
const ret = (openBlock(), createBlock(VaporSlot, props))
4040
ret.vs = { slot, fallback }
4141
return ret

packages/runtime-vapor/__tests__/vdomInterop.spec.ts

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { defineComponent, h } from '@vue/runtime-dom'
1+
import { createVNode, defineComponent, h, renderSlot } from '@vue/runtime-dom'
22
import { makeInteropRender } from './_utils'
33
import { createComponent, defineVaporComponent } from '../src'
44

@@ -9,7 +9,65 @@ describe('vdomInterop', () => {
99

1010
describe.todo('emit', () => {})
1111

12-
describe.todo('slots', () => {})
12+
describe('slots', () => {
13+
test('basic', () => {
14+
const VDomChild = defineComponent({
15+
setup(_, { slots }) {
16+
return () => renderSlot(slots, 'default')
17+
},
18+
})
19+
20+
const VaporChild = defineVaporComponent({
21+
setup() {
22+
return createComponent(
23+
VDomChild as any,
24+
null,
25+
{
26+
default: () => document.createTextNode('default slot'),
27+
},
28+
true,
29+
)
30+
},
31+
})
32+
33+
const { html } = define({
34+
setup() {
35+
return () => h(VaporChild as any)
36+
},
37+
}).render()
38+
39+
expect(html()).toBe('default slot')
40+
})
41+
42+
test('functional slot', () => {
43+
const VDomChild = defineComponent({
44+
setup(_, { slots }) {
45+
return () => createVNode(slots.default!)
46+
},
47+
})
48+
49+
const VaporChild = defineVaporComponent({
50+
setup() {
51+
return createComponent(
52+
VDomChild as any,
53+
null,
54+
{
55+
default: () => document.createTextNode('default slot'),
56+
},
57+
true,
58+
)
59+
},
60+
})
61+
62+
const { html } = define({
63+
setup() {
64+
return () => h(VaporChild as any)
65+
},
66+
}).render()
67+
68+
expect(html()).toBe('default slot')
69+
})
70+
})
1371

1472
describe.todo('provide', () => {})
1573

packages/runtime-vapor/src/componentProps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export function getAttrFromRawProps(rawProps: RawProps, key: string): unknown {
185185
source = dynamicSources[i]
186186
isDynamic = isFunction(source)
187187
source = isDynamic ? (source as Function)() : source
188-
if (hasOwn(source, key)) {
188+
if (source && hasOwn(source, key)) {
189189
const value = isDynamic ? source[key] : source[key]()
190190
if (merged) {
191191
merged.push(value)

packages/runtime-vapor/src/vdomInterop.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,11 @@ const vaporSlotPropsProxyHandler: ProxyHandler<
134134

135135
const vaporSlotsProxyHandler: ProxyHandler<any> = {
136136
get(target, key) {
137-
if (key === '_vapor') {
138-
return target
139-
} else {
140-
return target[key]
137+
const slot = target[key]
138+
if (isFunction(slot)) {
139+
slot.__vapor = true
141140
}
141+
return slot
142142
},
143143
}
144144

0 commit comments

Comments
 (0)