Skip to content

Commit 23a22cb

Browse files
committed
support slots in functional components
1 parent 154e17a commit 23a22cb

File tree

3 files changed

+35
-9
lines changed

3 files changed

+35
-9
lines changed

src/core/instance/render.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ export function renderMixin (Vue: Class<Component>) {
5656
vm.$vnode = _parentVnode
5757
// resolve slots. becaues slots are rendered in parent scope,
5858
// we set the activeInstance to parent.
59-
if (_renderChildren) {
60-
resolveSlots(vm, _renderChildren)
61-
}
59+
vm.$slots = resolveSlots(_renderChildren)
6260
// render self
6361
let vnode
6462
try {
@@ -179,11 +177,13 @@ export function renderMixin (Vue: Class<Component>) {
179177
}
180178
}
181179

182-
function resolveSlots (
183-
vm: Component,
184-
renderChildren: Array<any> | () => Array<any> | string
185-
) {
186-
const slots = vm.$slots = {}
180+
export function resolveSlots (
181+
renderChildren?: Array<any> | () => Array<any> | string
182+
): Object {
183+
const slots = {}
184+
if (!renderChildren) {
185+
return slots
186+
}
187187
const children = normalizeChildren(renderChildren) || []
188188
const defaultSlot = []
189189
let name, child
@@ -208,4 +208,5 @@ function resolveSlots (
208208
)) {
209209
slots.default = defaultSlot
210210
}
211+
return slots
211212
}

src/core/vdom/create-component.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Vue from '../instance/index'
44
import VNode from './vnode'
55
import { normalizeChildren } from './helpers'
66
import { callHook } from '../instance/lifecycle'
7+
import { resolveSlots } from '../instance/render'
78
import { warn, isObject, hasOwn, hyphenate, validateProp } from '../util/index'
89

910
const hooks = { init, prepatch, insert, destroy }
@@ -79,7 +80,13 @@ export function createComponent (
7980
return Ctor.options.render.call(
8081
null,
8182
parent.$createElement,
82-
{ props, parent, data, children: () => normalizeChildren(children) }
83+
{
84+
props,
85+
parent,
86+
data,
87+
children: () => normalizeChildren(children),
88+
slots: () => resolveSlots(children)
89+
}
8390
)
8491
}
8592

test/unit/features/options/functional.spec.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,24 @@ describe('Options functional', () => {
2222
}).then(done)
2323
})
2424

25+
it('should support slots', () => {
26+
const vm = new Vue({
27+
data: { test: 'foo' },
28+
template: '<div><wrap><div slot="a">foo</div><div slot="b">bar</div></wrap></div>',
29+
components: {
30+
wrap: {
31+
functional: true,
32+
props: ['msg'],
33+
render (h, { slots }) {
34+
slots = slots()
35+
return h('div', null, [slots.b, slots.a])
36+
}
37+
}
38+
}
39+
}).$mount()
40+
expect(vm.$el.innerHTML).toBe('<div><div>bar</div><div>foo</div></div>')
41+
})
42+
2543
it('should let vnode raw data pass through', done => {
2644
const onValid = jasmine.createSpy('valid')
2745
const vm = new Vue({

0 commit comments

Comments
 (0)