]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(inject): fix support for inject option default function
authorEvan You <yyx990803@gmail.com>
Fri, 4 Sep 2020 16:00:37 +0000 (12:00 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 4 Sep 2020 16:07:30 +0000 (12:07 -0400)
fix #2050

packages/runtime-core/__tests__/apiOptions.spec.ts
packages/runtime-core/src/apiInject.ts
packages/runtime-core/src/componentOptions.ts

index 4504649bc5e8ecc4471e7426d7d86e7cd18a4e3d..4dd1910bfa15faaf89f9afa59cd817f442e67e6f 100644 (file)
@@ -241,7 +241,7 @@ describe('api: options', () => {
   })
 
   test('provide/inject', () => {
-    const Root = {
+    const Root = defineComponent({
       data() {
         return {
           a: 1
@@ -253,45 +253,38 @@ describe('api: options', () => {
         }
       },
       render() {
-        return [h(ChildA), h(ChildB), h(ChildC), h(ChildD)]
-      }
-    } as any
-    const ChildA = {
-      inject: ['a'],
-      render() {
-        return this.a
-      }
-    } as any
-    const ChildB = {
-      // object alias
-      inject: { b: 'a' },
-      render() {
-        return this.b
+        return [h(ChildA), h(ChildB), h(ChildC), h(ChildD), h(ChildE)]
       }
-    } as any
-    const ChildC = {
-      inject: {
-        b: {
-          from: 'a'
+    })
+
+    const defineChild = (injectOptions: any, injectedKey = 'b') =>
+      ({
+        inject: injectOptions,
+        render() {
+          return this[injectedKey]
         }
-      },
-      render() {
-        return this.b
+      } as any)
+
+    const ChildA = defineChild(['a'], 'a')
+    const ChildB = defineChild({ b: 'a' })
+    const ChildC = defineChild({
+      b: {
+        from: 'a'
       }
-    } as any
-    const ChildD = {
-      inject: {
-        b: {
-          from: 'c',
-          default: 2
-        }
-      },
-      render() {
-        return this.b
+    })
+    const ChildD = defineChild({
+      b: {
+        from: 'c',
+        default: 2
       }
-    } as any
-
-    expect(renderToString(h(Root))).toBe(`1112`)
+    })
+    const ChildE = defineChild({
+      b: {
+        from: 'c',
+        default: () => 3
+      }
+    })
+    expect(renderToString(h(Root))).toBe(`11123`)
   })
 
   test('lifecycle', async () => {
index 2e1d428d1b9e3dab8b5398847e4da6432d919dba..02dc69e9d298d8e2fabce896131d233ca130a4cb 100644 (file)
@@ -1,3 +1,4 @@
+import { isFunction } from '@vue/shared'
 import { currentInstance } from './component'
 import { currentRenderingInstance } from './componentRenderUtils'
 import { warn } from './warning'
@@ -27,10 +28,15 @@ export function provide<T>(key: InjectionKey<T> | string, value: T) {
 }
 
 export function inject<T>(key: InjectionKey<T> | string): T | undefined
-export function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T
+export function inject<T>(
+  key: InjectionKey<T> | string,
+  defaultValue: T,
+  treatDefaultAsFactory?: boolean
+): T
 export function inject(
   key: InjectionKey<any> | string,
-  defaultValue?: unknown
+  defaultValue?: unknown,
+  treatDefaultAsFactory = false
 ) {
   // fallback to `currentRenderingInstance` so that this can be called in
   // a functional component
@@ -41,7 +47,9 @@ export function inject(
       // TS doesn't allow symbol as index type
       return provides[key as string]
     } else if (arguments.length > 1) {
-      return defaultValue
+      return treatDefaultAsFactory && isFunction(defaultValue)
+        ? defaultValue()
+        : defaultValue
     } else if (__DEV__) {
       warn(`injection "${String(key)}" not found.`)
     }
index fd473714771051b0f5bd2cdf4c1636645ca6ddb4..0eb24a6c2a13a235af5bce9747cc52f5ce2d5c46 100644 (file)
@@ -457,7 +457,11 @@ export function applyOptions(
       for (const key in injectOptions) {
         const opt = injectOptions[key]
         if (isObject(opt)) {
-          ctx[key] = inject(opt.from, opt.default)
+          ctx[key] = inject(
+            opt.from,
+            opt.default,
+            true /* treat default function as factory */
+          )
         } else {
           ctx[key] = inject(opt)
         }