provide 和 inject 主要為高階插件/組件庫提供用例。并不推薦直接用于應(yīng)用程序代碼中。是 2.2.0 版本 新增的。
這對選項需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在起上下游關(guān)系成立的時間里始終生效。
provide 選項應(yīng)該是一個對象或返回一個對象的函數(shù)。
inject 選項應(yīng)該是:一個字符串?dāng)?shù)組,或一個對象
使用場景:由于 vue 有$parent 屬性可以讓子組件訪問父組件。但孫組件想要訪問祖先組件就比較困難。通過 provide/inject 可以輕松實現(xiàn)跨級訪問祖先組件的數(shù)據(jù)
一種最常見的用法是刷新 vue 組件
app.vue
<template>
<div
id="app"
>
<router-view
v-if="isRouterAlive"
/>
</div>
</template>
<script>
export default {
name: 'App',
components: {
MergeTipDialog,
BreakNetTip
},
data () {
return {
isShow: false,
isRouterAlive: true
},
// 父組件中返回要傳給下級的數(shù)據(jù)
provide () {
return {
reload: this.reload
}
},
methods: {
reload () {
this.isRouterAlive = false
this.$nextTick(() => {
this.isRouterAlive = true
})
}
}
}
</script>
// 后代組件
<template>
<popup-assign
:id="id"
@success="successHandle"
>
<div class="confirm-d-tit"><span class="gray-small-btn">{{ name }}</span></div>
<strong>將被分配給</strong>
<a
slot="reference"
class="unite-btn"
>
指派
</a>
</popup-assign>
</template>
<script>
import PopupAssign from '../PopupAssign'
export default {
//引用vue reload方法
inject: ['reload'],
components: {
PopupAssign
},
methods: {
// ...mapActions(['freshList']),
async successHandle () {
this.reload()
}
}
}
</script>
這樣就實現(xiàn)了子組件調(diào)取 reload 方法就實現(xiàn)了刷新 vue 組件的功能,個人認(rèn)為它實現(xiàn)了組件跨越組件傳遞數(shù)據(jù)方法。
下面一個例子祖組件的數(shù)據(jù),祖孫元素調(diào)取
<template>
<div id="app"></div>
</template>
<script>
export default {
data () {
return {
datas: [
{
id: 1,
label: '產(chǎn)品一'
},
{
id: 1,
label: '產(chǎn)品二'
},
{
id: 1,
label: '產(chǎn)品三'
}
]
}
},
provide {
return {
datas: this.datas
}
}
}
</script>
后代組件
<template>
<div>
<ul>
<li v-for="(item, index) in datas" :key="index">
{{ item.label }}
</li>
</ul>
</div>
</template>
<script>
export default {
inject: ['datas']
}
</script>
后代元素引入被注入數(shù)據(jù) datas,并在組件內(nèi)循環(huán)輸出
實際上,你可以把依賴注入看作一部分“大范圍有效的 prop”,除了:
祖先組件不需要知道哪些后代組件使用它提供的屬性
后代組件不需要知道被注入的屬性來自哪里
提示:provide 和 inject 綁定并不是可響應(yīng)的。這是刻意為之的。然而,如果你傳入了一個可監(jiān)聽的對象,那么其對象的屬性還是可響應(yīng)的。