provide和inject依賴註入 點擊打開視頻講解更詳細 在此之前,在我們描述訪問父級組件實例的時候,展示過一個類似這樣的例子: <google-map> <google-map-region v-bind:shape="cityBoundaries"> <google-map-markers ...
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>
父組件:src\components\HelloWorld.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>
孫子組件:src\components\Category.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>