Skip to content

Commit 127949d

Browse files
committed
add provide/inject on functional context
1 parent 2944515 commit 127949d

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

Diff for: src/core/instance/inject.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* @flow */
22

33
import { hasSymbol } from 'core/util/env'
4+
import { extend } from 'shared/util'
45

56
export function initProvide (vm: Component) {
67
const provide = vm.$options.provide
@@ -12,11 +13,16 @@ export function initProvide (vm: Component) {
1213
}
1314

1415
export function initInjections (vm: Component) {
15-
const inject: any = vm.$options.inject
16+
const result = resolveInject(vm.$options.inject, vm)
17+
extend(vm, result)
18+
}
19+
20+
export function resolveInject (inject: any, vm: Component): ?Object {
1621
if (inject) {
1722
// inject is :any because flow is not smart enough to figure out cached
1823
// isArray here
1924
const isArray = Array.isArray(inject)
25+
const result = Object.create(null)
2026
const keys = isArray
2127
? inject
2228
: hasSymbol
@@ -29,11 +35,12 @@ export function initInjections (vm: Component) {
2935
let source = vm
3036
while (source) {
3137
if (source._provided && provideKey in source._provided) {
32-
vm[key] = source._provided[provideKey]
38+
result[key] = source._provided[provideKey]
3339
break
3440
}
3541
source = source.$parent
3642
}
3743
}
44+
return result
3845
}
3946
}

Diff for: src/core/vdom/create-component.js

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import VNode from './vnode'
44
import { createElement } from './create-element'
55
import { resolveConstructorOptions } from '../instance/init'
66
import { resolveSlots } from '../instance/render-helpers/resolve-slots'
7+
import { resolveInject } from '../instance/inject'
78

89
import {
910
warn,
@@ -183,11 +184,13 @@ function createFunctionalComponent (
183184
// gets a unique context - this is necessary for correct named slot check
184185
const _context = Object.create(context)
185186
const h = (a, b, c, d) => createElement(_context, a, b, c, d, true)
187+
const injections = resolveInject(Ctor.options.inject, _context)
186188
const vnode = Ctor.options.render.call(null, h, {
187189
props,
188190
data,
189191
parent: context,
190192
children,
193+
injections,
191194
slots: () => resolveSlots(children, context)
192195
})
193196
if (vnode instanceof VNode) {

Diff for: test/unit/features/options/inject.spec.js

+23
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,29 @@ describe('Options provide/inject', () => {
144144
expect(child.baz).toBe(3)
145145
})
146146

147+
// Github issue #5194
148+
it('should work with functional', () => {
149+
new Vue({
150+
template: `<child/>`,
151+
provide: {
152+
foo: 1,
153+
bar: false
154+
},
155+
components: {
156+
child: {
157+
functional: true,
158+
inject: ['foo', 'bar'],
159+
render (h, context) {
160+
const { injections } = context
161+
injected = [injections.foo, injections.bar]
162+
}
163+
}
164+
}
165+
}).$mount()
166+
167+
expect(injected).toEqual([1, false])
168+
})
169+
147170
if (typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys)) {
148171
it('with Symbol keys', () => {
149172
const s = Symbol()

Diff for: types/options.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export interface RenderContext {
6969
slots(): any;
7070
data: VNodeData;
7171
parent: Vue;
72+
injections: any
7273
}
7374

7475
export interface PropOptions {

0 commit comments

Comments
 (0)