企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 方法五、provide/inject #### 1.简介 Vue2.2.0新增API,这对选项需要一起使用,**以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效**。一言而蔽之:祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。 **provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系**。 #### 2.举个例子 假设有两个组件: A.vue 和 B.vue,B 是 A 的子组件 ~~~ // A.vue export default { provide: { name: '浪里行舟' } } ~~~ ~~~ // B.vue export default { inject: ['name'], mounted () { console.log(this.name); // 浪里行舟 } } ~~~ 可以看到,在 A.vue 里,我们设置了一个 **provide: name**,值为 浪里行舟,它的作用就是将 **name** 这个变量提供给它的所有子组件。而在 B.vue 中,通过 `inject` 注入了从 A 组件中提供的 **name** 变量,那么在组件 B 中,就可以直接通过 **this.name** 访问这个变量了,它的值也是 浪里行舟。这就是 provide / inject API 最核心的用法。 需要注意的是:**provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的**\----vue官方文档 所以,上面 A.vue 的 name 如果改变了,B.vue 的 this.name 是不会改变的,仍然是 浪里行舟。 #### 3.provide与inject 怎么实现数据响应式 一般来说,有两种办法: * provide祖先组件的实例,然后在子孙组件中注入依赖,这样就可以在子孙组件中直接修改祖先组件的实例的属性,不过这种方法有个缺点就是这个实例上挂载很多没有必要的东西比如props,methods * 使用2.6最新API Vue.observable 优化响应式 provide(推荐) 我们来看个例子:孙组件D、E和F获取A组件传递过来的color值,并能实现数据响应式变化,即A组件的color变化后,组件D、E、F会跟着变(核心代码如下:) ![](https://img.kancloud.cn/46/dc/46dc48f2a8691d4ad2c2d15fb7b9292c_528x348.png) ~~~ // A 组件 <div> <h1>A 组件</h1> <button @click="() => changeColor()">改变color</button> <ChildrenB /> <ChildrenC /> </div> ...... data() { return { color: "blue" }; }, // provide() { // return { // theme: { // color: this.color //这种方式绑定的数据并不是可响应的 // } // 即A组件的color变化后,组件D、E、F不会跟着变 // }; // }, provide() { return { theme: this//方法一:提供祖先组件的实例 }; }, methods: { changeColor(color) { if (color) { this.color = color; } else { this.color = this.color === "blue" ? "red" : "blue"; } } } // 方法二:使用2.6最新API Vue.observable 优化响应式 provide // provide() { // this.theme = Vue.observable({ // color: "blue" // }); // return { // theme: this.theme // }; // }, // methods: { // changeColor(color) { // if (color) { // this.theme.color = color; // } else { // this.theme.color = this.theme.color === "blue" ? "red" : "blue"; // } // } // } ~~~ ~~~ // F 组件 <template functional> <div class="border2"> <h3 :style="{ color: injections.theme.color }">F 组件</h3> </div> </template> <script> export default { inject: { theme: { //函数式组件取值不一样 default: () => ({}) } } }; </script> ~~~ 虽说provide 和 inject 主要为高阶插件/组件库提供用例,但如果你能在业务中熟练运用,可以达到事半功倍的效果!