Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

正常使用provide的方式:

1
2
3
4
// 父组件中:
provide:{
  for: 'demo'
}

这样子组件中无论多深的子组件都可以使用:

1
2
3
4
5
6
7
// 子组件
inject:['for'],
data(){
  return{
    demo: this.for
  }
}

但是上面的写法有一定的问题,
比如父组件中for变量的值如果我们是在mounted方法中请求后台数据再更改provide中for的值,
那么在子组件中获取不到更改后的for的值。

这时候就需要换一种写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 父组件中:
data () {
return {
for: {}
}
},
provide() {
return {
provObj: this.for
};
},
mounted() {
setTimeout(() => {
this.for.fp= 'demo';
}, 2000);
}
1
2
3
4
5
6
7
// 子组件中:
inject:['provObj'],
data(){
  return{
    demo: this.provObj.fp
  }
}

provide源码
使用defineReactive, 让provide变为响应式的, 所以根元素属性 this.for 无效,必须监听下一级属性 this.for.fp

1
2
3
4
5
6
7
8
9
10
11
export function initInjections (vm: Component) {
const result = resolveInject(vm.$options.inject, vm)
if (result) {
observerState.shouldConvert = false
Object.keys(result).forEach(key => {
`defineReactive(vm, key, result[key])` // defineReactive
})
observerState.shouldConvert = true
}
}

inject源码


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
export function resolveInject (inject: any, vm: Component): ?Object {
if (inject) {
// inject 是 :any 类型因为流没有智能到能够指出缓存
const result = Object.create(null)
// 获取 inject 选项的 key 数组
const keys = hasSymbol
? Reflect.ownKeys(inject).filter(key => {
/* istanbul ignore next */
return Object.getOwnPropertyDescriptor(inject, key).enumerable
})
: Object.keys(inject)

for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const provideKey = inject[key].from
let source = vm
while (source) {
if (source._provided && provideKey in source._provided) {
result[key] = source._provided[provideKey]
break
}
source = source.$parent
}
if (!source) {
if ('default' in inject[key]) {
const provideDefault = inject[key].default
result[key] = typeof provideDefault === 'function'
? provideDefault.call(vm)
: provideDefault
} else if (process.env.NODE_ENV !== 'production') {
warn(`Injection "${key}" not found`, vm)
}
}
}
return result
}
}

评论