Browse Source

Merge inject when extending a component (#5827)

* 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 8466a2866b868de00f755b80e5b3a3dc8bdc2d86.
JK 9 years ago
parent
commit
080c387d49
3 changed files with 46 additions and 6 deletions
  1. 2 6
      src/core/instance/inject.js
  2. 15 0
      src/core/util/options.js
  3. 29 0
      test/unit/features/options/inject.spec.js

+ 2 - 6
src/core/instance/inject.js

@@ -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) {

+ 15 - 0
src/core/util/options.js

@@ -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
@@ -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.
  */
@@ -280,6 +294,7 @@ export function mergeOptions (
   }
 
   normalizeProps(child)
+  normalizeInject(child)
   normalizeDirectives(child)
   const extendsFrom = child.extends
   if (extendsFrom) {

+ 29 - 0
test/unit/features/options/inject.spec.js

@@ -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({