vue中provide和inject的用法及說(shuō)明(vue組件爺孫傳值)
provide和inject的用法(vue組件爺孫傳值)
聊聊概念
成對(duì)出現(xiàn):provide和inject是成對(duì)出現(xiàn)的
作用:用于父組件向子孫組件傳遞數(shù)據(jù)
使用方法:provide在父組件中返回要傳給下級(jí)的數(shù)據(jù),inject在需要使用這個(gè)數(shù)據(jù)的子輩組件或者孫輩等下級(jí)組件中注入數(shù)據(jù)。
使用場(chǎng)景:由于vue有$parent屬性可以讓子組件訪問(wèn)父組件。但孫組件想要訪問(wèn)祖先組件就比較困難。通過(guò)provide/inject可以輕松實(shí)現(xiàn)跨級(jí)訪問(wèn)父組件的數(shù)據(jù)
使用示例DEMO
父組件:通過(guò)provide指定傳遞給子孫組件的值和方法
<template>
<div id="app">
我是父組件:{{message}}
<second></second>
</div>
</template>
<script>
import second from '../components/second.vue'
export default{
data(){
return{
message:'我們一起當(dāng)前端攻城獅!'
}
},
provide(){ // provide是一個(gè)匿名函數(shù),返回一個(gè)對(duì)象
return {
testmethods:this.testmethods,
message:this.message
}
},
methods:{
testmethods(){
console.log('調(diào)用了ProvideTest這個(gè)組件')
}
},
components:{
second
}
}
</script>
<style lang="less" scoped>
</style>子組件:用inject接收父組件的值和方法,并且繼續(xù)套一個(gè)組件
<template>
<div id="app">
<p>second組件:{{message}}</p>
<third></third>
</div>
</template>
<script>
import third from './third.vue'
export default{
data(){
return{
}
},
inject:['message','testmethods'],
mounted() {
this.testmethods()
},
components:{
third
}
}
</script>
<style lang="less" scoped>
</style>重點(diǎn)來(lái)了,我們稱之為
孫組件:
<template>
<div id="app">
<p>third組件:{{message}}</p>
</div>
</template>
<script>
export default{
data(){
return{
}
},
//inject:['message','testmethods'], 簡(jiǎn)寫(xiě)
inject:{ // 詳細(xì)指定來(lái)源以及默認(rèn)值
message:{
from:'message', //表示從組件ProvideTest傳遞過(guò)來(lái)的
//default:'message' //默認(rèn)值
},
testmethods:{
form:'testmethods'
}
},
mounted() {
this.testmethods()
},
}
</script>
<style lang="less" scoped>
</style>效果下圖所示

vue中provide,inject遇到的一個(gè)坑
provide、inject一般用在組件間嵌套過(guò)多,而子組件一層層的傳遞很麻煩,此時(shí)通過(guò)provide、inject可以跨層傳遞。但是最近在使用的過(guò)程中發(fā)現(xiàn)一個(gè)問(wèn)題:
祖組件中data里的響應(yīng)式數(shù)據(jù)通過(guò)provide return以后,發(fā)現(xiàn)孫組件無(wú)法接受到最新的值
//祖組件
<template>
? ? <div> this is grandparent component</div>
</template>
<script>
export {
? ? name:"grandparent",
? ? data(){
? ? ? ? ? ? return{
? ? ? ? ? ? ? hasMeal:false?
? ? ? ? }
? ? },
? ? provide(){
? ? ? ? return{
? ? ? ? ? ? hasMeal:this.hasMeal ? ? ? ?
? ? ? ? }
? ? },
? ? create(){
? ? ? fetch(xxx).then(res=>{
? ? ? ? ? ? this.hasMeal=res.data.hasMeal ?//此時(shí)是true
? ? ? ? })
? ? }
}
</script>
///
孫組件
<template>
? ? <div> this is grandson component</div>
</template>
<script>
export {
? ? name:"grandparent",
? ? data(){
? ? ? ? ? ? return{
? ? ? ? }
? ? },
? ? inject:['hasMeal'],
? ? create(){
? ? ? ? console.log(this.hasMeal) ? ?//false
? ? }
}
</script>hasMeal經(jīng)過(guò)異步請(qǐng)求以后變成了true,原本期待provide最后return的值是最新的值時(shí)true,結(jié)果在孫組件頁(yè)面打印this.hasMeal發(fā)現(xiàn)。
還是false?那是否是provide在return之前的this.hasMeal還是false呢?
經(jīng)過(guò)測(cè)試發(fā)現(xiàn),果不其然。進(jìn)一步證明。provide里如果直接return data里的值。是不能被響應(yīng)式處理的。
如何解決?
//祖組件
<template>
? ? <div> this is grandparent component</div>
</template>
<script>
export {
? ? name:"grandparent",
? ? data(){
? ? ? ? ? ? return{
? ? ? ? ? ? ? hasMeal:false?
? ? ? ? }
? ? },
? ? provide:()=>{
? ? ? ? return{
? ? ? ? ? ? hasMeal:this.hasMeal ? ? ? ?
? ? ? ? }
? ? },
? ? create(){
? ? ? fetch(xxx).then(res=>{
? ? ? ? ? ? this.hasMeal=res.data.hasMeal ?//此時(shí)是true
? ? ? ? })
? ? }
}
</script>
///
孫組件
<template>
? ? <div> this is grandson component</div>
</template>
<script>
export {
? ? name:"grandparent",
? ? data(){
? ? ? ? ? ? return{
? ? ? ? }
? ? },
? ? inject:['hasMeal'],
? ? create(){
? ? ? ? console.log(this.hasMeal()) ? ?//true
? ? }
}
</script>把provide變成一個(gè)箭頭函數(shù)。然后在孫頁(yè)面通過(guò)執(zhí)行這個(gè)函數(shù)的方式拿到函數(shù)返回的結(jié)果就可以拿到最新的值。也就間接變成了響應(yīng)式的了
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue 動(dòng)態(tài)組件與 v-once 指令的實(shí)現(xiàn)
這篇文章主要介紹了Vue 動(dòng)態(tài)組件與 v-once 指令的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
vue?點(diǎn)擊按鈕?路由跳轉(zhuǎn)指定頁(yè)面的實(shí)現(xiàn)方式
這篇文章主要介紹了vue?點(diǎn)擊按鈕?路由跳轉(zhuǎn)指定頁(yè)面的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
詳解vue2.0組件通信各種情況總結(jié)與實(shí)例分析
本篇文章主要介紹了詳解vue2.0組件通信各種情況總結(jié)與實(shí)例分析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
微信內(nèi)置開(kāi)發(fā) iOS修改鍵盤(pán)換行為搜索的解決方案
今天小編就為大家分享一篇微信內(nèi)置開(kāi)發(fā) iOS修改鍵盤(pán)換行為搜索的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11
基于 Vue 實(shí)現(xiàn)一個(gè)酷炫的 menu插件
本文給大家介紹基于 Vue 實(shí)現(xiàn)一個(gè)酷炫的 menu插件,此篇教程需要大家具備一定的css和vue基礎(chǔ)知識(shí),本文分步驟給大家介紹的非常詳細(xì),需要的朋友參考下吧2017-11-11
vue+axios 攔截器實(shí)現(xiàn)統(tǒng)一token的案例
這篇文章主要介紹了vue+axios 攔截器實(shí)現(xiàn)統(tǒng)一token的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09

