Просмотр исходного кода

separate provide/inject resolve timing to allow data/props to rely on injections

Evan You 9 лет назад
Родитель
Сommit
16765db9a4

+ 3 - 2
src/core/instance/init.js

@@ -6,8 +6,8 @@ import { initProxy } from './proxy'
 import { initState } from './state'
 import { initRender } from './render'
 import { initEvents } from './events'
-import { initInjections } from './inject'
 import { initLifecycle, callHook } from './lifecycle'
+import { initProvide, initInjections } from './inject'
 import { extend, mergeOptions, formatComponentName } from '../util/index'
 
 let uid = 0
@@ -49,8 +49,9 @@ export function initMixin (Vue: Class<Component>) {
     initEvents(vm)
     initRender(vm)
     callHook(vm, 'beforeCreate')
+    initInjections(vm) // resolve injections before data/props
     initState(vm)
-    initInjections(vm)
+    initProvide(vm) // resolve provide after data/props
     callHook(vm, 'created')
 
     /* istanbul ignore if */

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

@@ -2,14 +2,17 @@
 
 import { hasSymbol } from 'core/util/env'
 
-export function initInjections (vm: Component) {
+export function initProvide (vm: Component) {
   const provide = vm.$options.provide
-  const inject: any = vm.$options.inject
   if (provide) {
     vm._provided = typeof provide === 'function'
       ? provide.call(vm)
       : provide
   }
+}
+
+export function initInjections (vm: Component) {
+  const inject: any = vm.$options.inject
   if (inject) {
     // inject is :any because flow is not smart enough to figure out cached
     // isArray here

+ 21 - 3
test/unit/features/options/inject.spec.js

@@ -115,15 +115,33 @@ describe('Options provide/inject', () => {
     expect(injected).toEqual([false, 2])
   })
 
-  it('self-inject', () => {
+  it('inject before resolving data/props', () => {
     const vm = new Vue({
       provide: {
         foo: 1
+      }
+    })
+
+    const child = new Vue({
+      parent: vm,
+      inject: ['foo'],
+      data () {
+        return {
+          bar: this.foo + 1
+        }
       },
-      inject: ['foo']
+      props: {
+        baz: {
+          default () {
+            return this.foo + 2
+          }
+        }
+      }
     })
 
-    expect(vm.foo).toBe(1)
+    expect(child.foo).toBe(1)
+    expect(child.bar).toBe(2)
+    expect(child.baz).toBe(3)
   })
 
   if (typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys)) {