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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy