051_末晨曦Vue技术_处理边界情况之provide和inject依赖注入

  • 051_末晨曦Vue技术_处理边界情况之provide和inject依赖注入已关闭评论
  • 21 次浏览
  • A+
所属分类:Web前端
摘要

点击打开视频讲解更详细在此之前,在我们描述访问父级组件实例的时候,展示过一个类似这样的例子:


provide和inject依赖注入

点击打开视频讲解更详细

在此之前,在我们描述访问父级组件实例的时候,展示过一个类似这样的例子:

<google-map>   <google-map-region v-bind:shape="cityBoundaries">     <google-map-markers v-bind:places="iceCreamShops"></google-map-markers>   </google-map-region> </google-map> 

在这个组件里,所有<google-map>的后代都需要访问一个 getMap 方法,以便知道要跟哪个地图进行交互。不幸的是,使用 $parent property 无法很好的扩展到更深层级的嵌套组件上。这也是依赖注入的用武之地,它用到了两个新的实例选项:provide 和 inject

provide 选项允许我们指定我们想要提供给后代组件的数据/方法。在这个例子中,就是 <google-map> 内部的 getMap 方法:

provide: function () {   return {     getMap: this.getMap   } } 

然后在任何后代组件里,我们都可以使用 inject 选项来接收指定的我们想要添加在这个实例上的 property:

inject: ['getMap'] 

相比 $parent 来说,这个用法可以让我们在任意后代组件中访问 getMap,而不需要暴露整个 <google-map> 实例。这允许我们更好的持续研发该组件,而不需要担心我们可能会改变/移除一些子组件依赖的东西。同时这些组件之间的接口是始终明确定义的,就和 props 一样。

实际上,你可以把依赖注入看作一部分“大范围有效的 prop”,除了:

  • 祖先组件不需要知道哪些后代组件使用它提供的 property
  • 后代组件不需要知道被注入的 property 来自哪里

完整案例:

祖先组件

<template>   <div id="app">     App {{ name }}     {{ obj.name }}     <button @click="changeName">改变</button>     <HelloWorld></HelloWorld>   </div> </template>  <script> import HelloWorld from './components/HelloWorld' export default {   name: 'App',   data(){     return {       name:'末晨曦吖',       obj:{         name:'漫天'       }     }    },   mounted(){        },   provide () {     return {       name: this.name,  //基本数据类型 不是响应式的;       obj:this.obj,     //使用引用数据类型实现响应式效果;       change:this.change,       _this:this     }   },   components:{     HelloWorld   },   methods:{     changeName(){       this.name = '满天星辰',       this.obj.name = '不及你'     },     change(){       console.log('55555');     }   } } </script>  <style scoped>   </style> 

父组件:srccomponentsHelloWorld.vue

<template>   <div class="hello">     HelloWorld:{{ name }}     <Category></Category>   </div> </template>  <script> import Category from './Category.vue' export default {   name: 'HelloWorld',   props: [],   inject: ['name'],   data(){     return{            }   },   mounted(){        },   components:{     Category   },   methods:{        } } </script>  <style scoped>  </style> 

孙子组件:srccomponentsCategory.vue

<template>   <div class="category"> 	Category{{ name }} 	{{ obj.name }} 	{{ _this.name }}   </div> </template>  <script> export default {   name: "Category",   inject: ['name','change',"obj","_this"],   mounted(){     this.change() 	console.log(this._this)   }, }; </script>  <style scoped> </style>