一个父组件相对于其所有的后代组件,会作为**依赖提供者**。任何后代的组件树,无论层级有多深,都可以**注入**由父组件提供给整条链路的依赖
要为组件后代提供数据,需要使用到 `provide`选项:
先定义一个子组件 Child.vue
<template>
<DeepChild/>
</template>
<script>
import DeepChild from './DeepChild.vue'
export default{
components:{
DeepChild
}
}
</script>
然后定义一个父组件
<template>
<input v-model="message"/>
<Child/>
</template>
<script>
import Child from './Child.vue'
export default{
data(){
return{
message:'来自祖先的秘密',
obj:{
text:"来自祖先的大秘密"
}
}
},
components:{
Child
},provide(){
return{
//message:'来自祖先的消息',
//message:this.message,
message:()=>this.message,
obj:this.obj
}
}
}
</script>
最后定义一个祖先组件
Inject(注入)
祖先提供了暴露的数据,在使用该数据的子组件中我们需要注入之后才能使用。
声明要注入的数据属性
<template>
后代组件:{{localMsg}}<br/>
{{defaultMsg}}<br/>
对象 {{user.text}}
</template>
<script>
export default{
inject:{
message:{
from:'message'
},
defaultMsg:{
from:'defaultMsg',
default:'来自后代的反馈'
},
user:{
from:'obj',
default:()=>({text:'后代的忏悔值:admin'})
}
},computed:{
localMsg(){
return this.message()
}
}
}
</script>
注入会在组件自身的状态**之前**被解析,因此你可以在 `data()` 中访问到注入的属性:
结果:
如果我们想要用一个不同的本地属性名注入该属性,我们需要在 `inject` 选项的属性上使用对象的形式:
export default {
inject: {
/* 本地属性名 */ localMessage: {
from: /* 注入来源名 */ 'message'
}
}
}
这里,组件本地化了原注入名 `"message"` 所提供的的属性,并将其暴露为 `this.localMessage`。
注入默认值:默认情况下,`inject` 假设传入的注入名会被某个祖先链上的组件提供。如果该注入名的确没有任何组件提供,则会抛出一个运行时警告。
如果在注入一个值时不要求必须有提供者,那么我们应该声明一个默认值,和 props 类似:
export default {
// 当声明注入的默认值时
// 必须使用对象形式
inject: {
message: {
from: 'message', // 当与原注入名同名时,这个属性是可选的
default: 'default value'
},
user: {
// 对于非基础类型数据,如果创建开销比较大,或是需要确保每个组件实例
// 需要独立数据的,请使用工厂函数
default: () => ({ name: 'John' })
}
}
}