From e25635fdaed0d093a6709c52844ec2ed7d82feaa Mon Sep 17 00:00:00 2001 From: Popescu Dan Date: Thu, 5 Oct 2017 22:44:32 +0300 Subject: [PATCH] feat(inject): support providing default values for injections (#6322) --- src/core/instance/inject.js | 13 ++++++-- src/core/util/options.js | 11 +++++-- test/unit/features/options/inject.spec.js | 39 +++++++++++++++++++++++ 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/core/instance/inject.js b/src/core/instance/inject.js index 98887c48609..dd56e588855 100644 --- a/src/core/instance/inject.js +++ b/src/core/instance/inject.js @@ -49,7 +49,7 @@ export function resolveInject (inject: any, vm: Component): ?Object { for (let i = 0; i < keys.length; i++) { const key = keys[i] - const provideKey = inject[key] + const provideKey = inject[key].name let source = vm while (source) { if (source._provided && provideKey in source._provided) { @@ -58,8 +58,15 @@ export function resolveInject (inject: any, vm: Component): ?Object { } source = source.$parent } - if (process.env.NODE_ENV !== 'production' && !source) { - warn(`Injection "${key}" not found`, vm) + if (!source) { + if ('default' in inject[key]) { + const provideDefault = inject[key].default + result[key] = typeof provideDefault === 'function' + ? provideDefault.call(vm) + : provideDefault + } else if (process.env.NODE_ENV !== 'production') { + warn(`Injection "${key}" not found`, vm) + } } } return result diff --git a/src/core/util/options.js b/src/core/util/options.js index 70e4d015b4d..11a586961c4 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -270,10 +270,17 @@ function normalizeProps (options: Object) { */ function normalizeInject (options: Object) { const inject = options.inject + const normalized = options.inject = {} if (Array.isArray(inject)) { - const normalized = options.inject = {} for (let i = 0; i < inject.length; i++) { - normalized[inject[i]] = inject[i] + normalized[inject[i]] = { name: inject[i] } + } + } else if (isPlainObject(inject)) { + for (const key in inject) { + const val = inject[key] + normalized[key] = isPlainObject(val) + ? extend({ name: key }, val) + : { name: val } } } } diff --git a/test/unit/features/options/inject.spec.js b/test/unit/features/options/inject.spec.js index 86e3ada5736..99c78f960c8 100644 --- a/test/unit/features/options/inject.spec.js +++ b/test/unit/features/options/inject.spec.js @@ -370,6 +370,45 @@ describe('Options provide/inject', () => { expect(`Injection "__ob__" not found`).not.toHaveBeenWarned() }) + // Github issue #6097 + it('should not warn when injections cannot be found but have default value', () => { + const vm = new Vue({}) + new Vue({ + parent: vm, + inject: { + foo: { default: 1 }, + bar: { default: false }, + baz: { default: undefined } + }, + created () {} + }) + expect(`Injection "foo" not found`).not.toHaveBeenWarned() + expect(`Injection "bar" not found`).not.toHaveBeenWarned() + expect(`Injection "baz" not found`).not.toHaveBeenWarned() + }) + + it('should use provided value even if inject has default', () => { + const vm = new Vue({ + provide: { + foo: 1, + bar: false, + baz: undefined + } + }) + new Vue({ + parent: vm, + inject: { + foo: { default: 2 }, + bar: { default: 2 }, + baz: { default: 2 } + }, + created () { + injected = [this.foo, this.bar, this.baz] + } + }) + expect(injected).toEqual([1, false, undefined]) + }) + // Github issue #6008 it('should merge provide from mixins (objects)', () => { const mixinA = { provide: { foo: 'foo' }}