diff --git a/src/core/vdom/create-functional-component.js b/src/core/vdom/create-functional-component.js index 78a73def132..655de0deee3 100644 --- a/src/core/vdom/create-functional-component.js +++ b/src/core/vdom/create-functional-component.js @@ -48,10 +48,16 @@ export function FunctionalRenderContext ( this.children = children this.parent = parent this.listeners = data.on || emptyObject - this.scopedSlots = data.scopedSlots || emptyObject this.injections = resolveInject(options.inject, parent) this.slots = () => resolveSlots(children, parent) + Object.defineProperty(this, 'scopedSlots', { + enumerable: true, + get () { + return normalizeScopedSlots(data.scopedSlots, this.slots()) + } + }) + // support for compiled functional template if (isCompiled) { // exposing $options for renderStatic() diff --git a/src/core/vdom/helpers/normalize-scoped-slots.js b/src/core/vdom/helpers/normalize-scoped-slots.js index 3672d7e7758..12454ebfad5 100644 --- a/src/core/vdom/helpers/normalize-scoped-slots.js +++ b/src/core/vdom/helpers/normalize-scoped-slots.js @@ -21,6 +21,7 @@ export function normalizeScopedSlots ( } res._normalized = true } + // expose normal slots on scopedSlots if (normalSlots !== emptyObject) { for (const key in normalSlots) { res[key] = () => normalSlots[key] diff --git a/test/unit/features/options/functional.spec.js b/test/unit/features/options/functional.spec.js index a4ae7ce4377..ea85eea8a7f 100644 --- a/test/unit/features/options/functional.spec.js +++ b/test/unit/features/options/functional.spec.js @@ -79,21 +79,25 @@ describe('Options functional', () => { document.body.removeChild(vm.$el) }) - it('should expose data.scopedSlots as scopedSlots', () => { + it('should expose scopedSlots on render context', () => { const vm = new Vue({ - template: '
{{ a }}
{{ a }}