Skip to content

Commit

Permalink
Merge inject when extending a component (#5827)
Browse files Browse the repository at this point in the history
* simply fix inject extends

* add comments for normalizeInject

* normalizeInect should return for non-array

* remove isArray branch in resolveInject

* add test case for extending injection

* Create options.js

* type of inject should be object now

* Revert "type of inject should be object now"

This reverts commit 8466a28.
  • Loading branch information
jkzing authored and yyx990803 committed Jun 15, 2017
1 parent 9831b40 commit 080c387
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
8 changes: 2 additions & 6 deletions src/core/instance/inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,14 @@ export function initInjections (vm: Component) {
export function resolveInject (inject: any, vm: Component): ?Object {
if (inject) {
// inject is :any because flow is not smart enough to figure out cached
// isArray here
const isArray = Array.isArray(inject)
const result = Object.create(null)
const keys = isArray
? inject
: hasSymbol
const keys = hasSymbol
? Reflect.ownKeys(inject)
: Object.keys(inject)

for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const provideKey = isArray ? key : inject[key]
const provideKey = inject[key]
let source = vm
while (source) {
if (source._provided && provideKey in source._provided) {
Expand Down
15 changes: 15 additions & 0 deletions src/core/util/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ strats.watch = function (parentVal: ?Object, childVal: ?Object): ?Object {
*/
strats.props =
strats.methods =
strats.inject =
strats.computed = function (parentVal: ?Object, childVal: ?Object): ?Object {
if (!childVal) return Object.create(parentVal || null)
if (!parentVal) return childVal
Expand Down Expand Up @@ -247,6 +248,19 @@ function normalizeProps (options: Object) {
options.props = res
}

/**
* Normalize all injections into Object-based format
*/
function normalizeInject (options: Object) {
const inject = options.inject
if (Array.isArray(inject)) {
const normalized = options.inject = {}
for (let i = 0; i < inject.length; i++) {
normalized[inject[i]] = inject[i]
}
}
}

/**
* Normalize raw function directives into object format.
*/
Expand Down Expand Up @@ -280,6 +294,7 @@ export function mergeOptions (
}

normalizeProps(child)
normalizeInject(child)
normalizeDirectives(child)
const extendsFrom = child.extends
if (extendsFrom) {
Expand Down
29 changes: 29 additions & 0 deletions test/unit/features/options/inject.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,35 @@ describe('Options provide/inject', () => {
})
})

it('should extend properly', () => {
const parent = Vue.extend({
template: `<span/>`,
inject: ['foo']
})

const child = parent.extend({
template: `<span/>`,
inject: ['bar'],
created () {
injected = [this.foo, this.bar]
}
})

new Vue({
template: `<div><parent/><child/></div>`,
provide: {
foo: 1,
bar: false
},
components: {
parent,
child
}
}).$mount()

expect(injected).toEqual([1, false])
})

it('should warn when injections has been modified', () => {
const key = 'foo'
const vm = new Vue({
Expand Down

0 comments on commit 080c387

Please sign in to comment.