inject.ts
2.47 KB
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
import { warn, hasSymbol, isFunction, isObject } from '../util/index'
import { defineReactive, toggleObserving } from '../observer/index'
import type { Component } from 'types/component'
import { resolveProvided } from 'v3/apiInject'
export function initProvide(vm: Component) {
const provideOption = vm.$options.provide
if (provideOption) {
const provided = isFunction(provideOption)
? provideOption.call(vm)
: provideOption
if (!isObject(provided)) {
return
}
const source = resolveProvided(vm)
// IE9 doesn't support Object.getOwnPropertyDescriptors so we have to
// iterate the keys ourselves.
const keys = hasSymbol ? Reflect.ownKeys(provided) : Object.keys(provided)
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
Object.defineProperty(
source,
key,
Object.getOwnPropertyDescriptor(provided, key)!
)
}
}
}
export function initInjections(vm: Component) {
const result = resolveInject(vm.$options.inject, vm)
if (result) {
toggleObserving(false)
Object.keys(result).forEach(key => {
/* istanbul ignore else */
if (__DEV__) {
defineReactive(vm, key, result[key], () => {
warn(
`Avoid mutating an injected value directly since the changes will be ` +
`overwritten whenever the provided component re-renders. ` +
`injection being mutated: "${key}"`,
vm
)
})
} else {
defineReactive(vm, key, result[key])
}
})
toggleObserving(true)
}
}
export function resolveInject(
inject: any,
vm: Component
): Record<string, any> | undefined | null {
if (inject) {
// inject is :any because flow is not smart enough to figure out cached
const result = Object.create(null)
const keys = hasSymbol ? Reflect.ownKeys(inject) : Object.keys(inject)
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
// #6574 in case the inject object is observed...
if (key === '__ob__') continue
const provideKey = inject[key].from
if (provideKey in vm._provided) {
result[key] = vm._provided[provideKey]
} else if ('default' in inject[key]) {
const provideDefault = inject[key].default
result[key] = isFunction(provideDefault)
? provideDefault.call(vm)
: provideDefault
} else if (__DEV__) {
warn(`Injection "${key as string}" not found`, vm)
}
}
return result
}
}