forked from vuejs/composition-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinject.ts
82 lines (73 loc) · 1.95 KB
/
inject.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { ComponentInstance } from '../component'
import {
hasOwn,
warn,
getCurrentInstanceForFn,
isFunction,
proxy,
} from '../utils'
import { getCurrentInstance } from '../runtimeContext'
const NOT_FOUND = {}
export interface InjectionKey<T> extends Symbol {}
function resolveInject(
provideKey: InjectionKey<any> | string,
vm: ComponentInstance
): any {
let source = vm
while (source) {
if (source._provided && hasOwn(source._provided, provideKey as PropertyKey)) {
return source._provided[provideKey as PropertyKey]
}
source = source.$parent
}
return NOT_FOUND
}
export function provide<T>(key: InjectionKey<T> | string, value: T): void {
const vm = getCurrentInstanceForFn('provide')?.proxy
if (!vm) return
if (!vm._provided) {
const provideCache = {}
proxy(vm, '_provided', {
get: () => provideCache,
set: (v: any) => Object.assign(provideCache, v),
})
}
vm._provided[key as string] = value
}
export function inject<T>(key: InjectionKey<T> | string): T | undefined
export function inject<T>(
key: InjectionKey<T> | string,
defaultValue: T,
treatDefaultAsFactory?: false
): T
export function inject<T>(
key: InjectionKey<T> | string,
defaultValue: T | (() => T),
treatDefaultAsFactory?: true
): T
export function inject(
key: InjectionKey<any> | string,
defaultValue?: unknown,
treatDefaultAsFactory = false
) {
const vm = getCurrentInstance()?.proxy
if (!vm) {
__DEV__ &&
warn(`inject() can only be used inside setup() or functional components.`)
return
}
if (!key) {
__DEV__ && warn(`injection "${String(key)}" not found.`, vm)
return defaultValue
}
const val = resolveInject(key, vm)
if (val !== NOT_FOUND) {
return val
} else if (arguments.length > 1) {
return treatDefaultAsFactory && isFunction(defaultValue)
? defaultValue()
: defaultValue
} else if (__DEV__) {
warn(`Injection "${String(key)}" not found.`, vm)
}
}