From fb6aa0609045e69a0b6050bc7b6466b63be8d69d Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Wed, 9 Jan 2019 22:18:14 +0100 Subject: [PATCH] feat(functional): add scopedSlots to context in functional components (#7941) --- src/core/vdom/create-functional-component.js | 1 + test/unit/features/options/functional.spec.js | 17 +++++++++++++++++ types/options.d.ts | 3 ++- types/test/options-test.ts | 1 + 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/core/vdom/create-functional-component.js b/src/core/vdom/create-functional-component.js index 8b6888e49e..78a73def13 100644 --- a/src/core/vdom/create-functional-component.js +++ b/src/core/vdom/create-functional-component.js @@ -48,6 +48,7 @@ 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) diff --git a/test/unit/features/options/functional.spec.js b/test/unit/features/options/functional.spec.js index b3446ac599..a4ae7ce437 100644 --- a/test/unit/features/options/functional.spec.js +++ b/test/unit/features/options/functional.spec.js @@ -79,6 +79,23 @@ describe('Options functional', () => { document.body.removeChild(vm.$el) }) + it('should expose data.scopedSlots as scopedSlots', () => { + const vm = new Vue({ + template: '

{{ a }}

', + components: { + wrap: { + functional: true, + render (h, { scopedSlots, data }) { + expect(data.scopedSlots).toBe(scopedSlots) + return data.scopedSlots.default('a') + } + } + } + }).$mount() + + expect(vm.$el.textContent).toBe('a') + }) + it('should support returning more than one root node', () => { const vm = new Vue({ template: `
`, diff --git a/types/options.d.ts b/types/options.d.ts index 0e98b4a962..08782da550 100644 --- a/types/options.d.ts +++ b/types/options.d.ts @@ -1,5 +1,5 @@ import { Vue, CreateElement, CombinedVueInstance } from "./vue"; -import { VNode, VNodeData, VNodeDirective } from "./vnode"; +import { VNode, VNodeData, VNodeDirective, ScopedSlot } from "./vnode"; type Constructor = { new (...args: any[]): any; @@ -140,6 +140,7 @@ export interface RenderContext { data: VNodeData; parent: Vue; listeners: { [key: string]: Function | Function[] }; + scopedSlots: { [key: string]: ScopedSlot }; injections: any } diff --git a/types/test/options-test.ts b/types/test/options-test.ts index 4041aad44b..de57e4c25e 100644 --- a/types/test/options-test.ts +++ b/types/test/options-test.ts @@ -381,6 +381,7 @@ Vue.component('functional-component', { context.slots(); context.data; context.parent; + context.scopedSlots; context.listeners.click; return createElement("div", {}, context.children); }