一、名词解析
provide:Object | () => Object
inject:Array | { [key: string]: string | Symbol | Object }
provide:提供依赖``是一个对象,或者是一个返回对象的函数。里面呢就包含要给子孙后代的东西,也就是属性和属性值。
inject: 注入依赖一个字符串数组,或者是一个对象。属性值可以是一个对象,包含from和default默认值。
provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。
这对选项是成对使用的。子孙组件想要获取祖先组件得资源,那么怎么办呢,总不能一直取父级往上吧,而且这样代码结构容易混乱。这个就是这对选项要干的事情。
const Child = {
inject: {
foo: {
from: 'bar',
default: 'foo'
}
}
}
from表示在可用的注入内容中搜索用的 key,default当然就是默认值。
二、示例
// 父级组件提供 'foo'
var Provider = {
provide: {
foo: 'bar'
},
// ...
}
// 子组件注入 'foo'
var Child = {
inject: ['foo'],
created () {
console.log(this.foo) // => "bar"
}
}
三、项目案例
父组件
项目最外层的布局组件layout.vue
<template>
<div>
<!-- 主内容 -->
<router-view></router-view>
</div>
</template>
<script>
export default {
name:'layout',
provide(){
return {
layout:this //这里的this值当前layout组件实例
box:'world'
}
},
data() {
return {
test:'hello'
}
},
}
</script>
这里就是我们说的provide,向下提供信息,这里提供的是当前的vue实例,相当于给了后代一个接口。这样在任何的后代组件中,都可以使用inject选项来接收指定的我们想要添加在这个实例上的属性。
子组件
layout.vue组件内的router-view 可能路由进来很多其它子孙组件,比如order.vue
export default {
name:'order',
inject:['layout','box'],
created(){
console.log(this.layout.test); //hello
console.log(this.box);// world
}
}
这样也就可以访问了,当做当前vue实例的属性。这样做的好处,相当于给了一个捷径,不用使用$parent一级一级的访问。
我们可以把依赖注入看做一部分“大范围有效的prop”,除了
祖先组件不需要知道哪些后代组件需要使用它提供的属性
后代组件不需要知道被注入的属性来自哪里