Skip to content

Commit ff97e28

Browse files
committed
fix: handle default slots in functional components;2C
1 parent 93a11e0 commit ff97e28

File tree

3 files changed

+46
-8
lines changed

3 files changed

+46
-8
lines changed

src/lib/create-instance.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ import { compileTemplate } from './compile-template'
1212
import createLocalVue from '../create-local-vue'
1313
import extractOptions from '../options/extract-options'
1414
import deleteMountingOptions from '../options/delete-mounting-options'
15+
import { compileToFunctions } from 'vue-template-compiler'
16+
17+
function createFunctionalSlots (slots = {}, h) {
18+
if (Array.isArray(slots.default)) {
19+
return slots.default.map(h)
20+
}
21+
22+
if (typeof slots.default === 'string') {
23+
return [h(compileToFunctions(slots.default))]
24+
}
25+
}
1526

1627
export default function createConstructor (
1728
component: Component,
@@ -29,13 +40,14 @@ export default function createConstructor (
2940
if (mountingOptions.context && typeof mountingOptions.context !== 'object') {
3041
throwError('mount.context must be an object')
3142
}
43+
3244
const clonedComponent = cloneDeep(component)
3345
component = {
3446
render (h) {
3547
return h(
3648
clonedComponent,
3749
mountingOptions.context || component.FunctionalRenderContext,
38-
mountingOptions.context && mountingOptions.context.children
50+
(mountingOptions.context && mountingOptions.context.children) || createFunctionalSlots(mountingOptions.slots, h)
3951
)
4052
}
4153
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
export default {
3+
name: 'component-with-slots',
4+
functional: true,
5+
render (h, ctx) {
6+
return h('div', ctx.data, ctx.slots().default)
7+
}
8+
}
9+
</script>

test/unit/specs/mount/options/slots.spec.js

+24-7
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,15 @@ import { compileToFunctions } from 'vue-template-compiler'
22
import mount from '~src/mount'
33
import Component from '~resources/components/component.vue'
44
import ComponentWithSlots from '~resources/components/component-with-slots.vue'
5+
import FunctionalComponentWithSlots from '~resources/components/functional-component-with-slots.vue'
56

67
describe('mount.slots', () => {
78
it('mounts component with default slot if passed component in slot object', () => {
8-
const wrapper = mount(ComponentWithSlots, { slots: { default: [Component] }})
9-
expect(wrapper.contains(Component)).to.equal(true)
10-
})
11-
12-
it('mounts component with default slot if passed object with template prop in slot object', () => {
13-
const wrapper = mount(ComponentWithSlots, { slots: { default: [Component] }})
9+
const wrapper = mount(ComponentWithSlots, { slots: { default: Component }})
1410
expect(wrapper.contains(Component)).to.equal(true)
1511
})
1612

17-
it('mounts component with default slot if passed component in slot object', () => {
13+
it('mounts component with default slot if passed component in array in slot object', () => {
1814
const wrapper = mount(ComponentWithSlots, { slots: { default: [Component] }})
1915
expect(wrapper.contains(Component)).to.equal(true)
2016
})
@@ -86,4 +82,25 @@ describe('mount.slots', () => {
8682
expect(wrapper.findAll(Component).length).to.equal(1)
8783
expect(Array.isArray(wrapper.vm.$slots.header)).to.equal(true)
8884
})
85+
86+
it.only('mounts functional component with default slot if passed component in slot object', () => {
87+
const wrapper = mount(FunctionalComponentWithSlots, { slots: { default: [Component] }})
88+
expect(wrapper.contains(Component)).to.equal(true)
89+
})
90+
91+
it.only('mounts component with default slot if passed component in slot object', () => {
92+
const wrapper = mount(FunctionalComponentWithSlots, { slots: { default: [Component] }})
93+
expect(wrapper.contains(Component)).to.equal(true)
94+
})
95+
96+
it.only('mounts component with default slot if passed object with template prop in slot object', () => {
97+
const compiled = compileToFunctions('<div id="div" />')
98+
const wrapper = mount(FunctionalComponentWithSlots, { slots: { default: [compiled] }})
99+
expect(wrapper.contains('#div')).to.equal(true)
100+
})
101+
102+
it.only('mounts component with default slot if passed string in slot object', () => {
103+
const wrapper = mount(FunctionalComponentWithSlots, { slots: { default: '<span />' }})
104+
expect(wrapper.contains('span')).to.equal(true)
105+
})
89106
})

0 commit comments

Comments
 (0)