Skip to content

Commit 326aef4

Browse files
committed
fix incorrect context for slot content created in functional components (fix vuejs#4315)
1 parent fba78d4 commit 326aef4

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

src/core/instance/lifecycle.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export function lifecycleMixin (Vue: Class<Component>) {
146146
}
147147
// resolve slots + force update if has children
148148
if (hasChildren) {
149-
vm.$slots = resolveSlots(renderChildren, vm._renderContext)
149+
vm.$slots = resolveSlots(renderChildren, parentVnode.context)
150150
vm.$forceUpdate()
151151
}
152152
}

src/core/instance/render.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ export function initRender (vm: Component) {
1414
vm.$vnode = null // the placeholder node in parent tree
1515
vm._vnode = null // the root of the child tree
1616
vm._staticTrees = null
17-
vm._renderContext = vm.$options._parentVnode && vm.$options._parentVnode.context
18-
vm.$slots = resolveSlots(vm.$options._renderChildren, vm._renderContext)
17+
const parentVnode = vm.$options._parentVnode
18+
const renderContext = parentVnode && parentVnode.context
19+
vm.$slots = resolveSlots(vm.$options._renderChildren, renderContext)
1920
vm.$scopedSlots = {}
2021
// bind the public createElement fn to this instance
2122
// so that we get proper render context inside it.
@@ -256,6 +257,7 @@ export function resolveSlots (
256257
let name, child
257258
for (let i = 0, l = children.length; i < l; i++) {
258259
child = children[i]
260+
debugger
259261
// named slots should only be respected if the vnode was rendered in the
260262
// same context.
261263
if ((child.context === context || child.functionalContext === context) &&

test/unit/features/component/component-slot.spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,4 +597,34 @@ describe('Component slot', () => {
597597
expect(vm.$el.textContent).toBe('2foobar')
598598
}).then(done)
599599
})
600+
601+
// #4315
602+
it('functional component passing slot content to stateful child component', done => {
603+
const ComponentWithSlots = {
604+
render (h) {
605+
return h('div', this.$slots.slot1)
606+
}
607+
}
608+
609+
const FunctionalComp = {
610+
functional: true,
611+
render (h) {
612+
return h(ComponentWithSlots, [h('span', { slot: 'slot1' }, 'foo')])
613+
}
614+
}
615+
616+
const vm = new Vue({
617+
data: { n: 1 },
618+
render (h) {
619+
return h('div', [this.n, h(FunctionalComp)])
620+
}
621+
}).$mount()
622+
623+
expect(vm.$el.textContent).toBe('1foo')
624+
vm.n++
625+
waitForUpdate(() => {
626+
// should not lose named slot
627+
expect(vm.$el.textContent).toBe('2foo')
628+
}).then(done)
629+
})
600630
})

0 commit comments

Comments
 (0)