Skip to content

Commit

Permalink
fix(inject): fix support for inject option default function
Browse files Browse the repository at this point in the history
fix #2050
  • Loading branch information
yyx990803 committed Sep 4, 2020
1 parent 6dbc6c4 commit d472461
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 40 deletions.
65 changes: 29 additions & 36 deletions packages/runtime-core/__tests__/apiOptions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ describe('api: options', () => {
})

test('provide/inject', () => {
const Root = {
const Root = defineComponent({
data() {
return {
a: 1
Expand All @@ -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 () => {
Expand Down
14 changes: 11 additions & 3 deletions packages/runtime-core/src/apiInject.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isFunction } from '@vue/shared'
import { currentInstance } from './component'
import { currentRenderingInstance } from './componentRenderUtils'
import { warn } from './warning'
Expand Down Expand Up @@ -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
Expand All @@ -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.`)
}
Expand Down
6 changes: 5 additions & 1 deletion packages/runtime-core/src/componentOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down

1 comment on commit d472461

@font-size
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good

Please sign in to comment.