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

vue中provide,inject遇到的一個坑
provide、inject一般用在組件間嵌套過多,而子組件一層層的傳遞很麻煩,此時通過provide、inject可以跨層傳遞。但是最近在使用的過程中發(fā)現(xiàn)一個問題:
祖組件中data里的響應式數(shù)據(jù)通過provide return以后,發(fā)現(xiàn)孫組件無法接受到最新的值
//祖組件
<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 ?//此時是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)過異步請求以后變成了true,原本期待provide最后return的值是最新的值時true,結果在孫組件頁面打印this.hasMeal發(fā)現(xiàn)。
還是false?那是否是provide在return之前的this.hasMeal還是false呢?
經(jīng)過測試發(fā)現(xiàn),果不其然。進一步證明。provide里如果直接return data里的值。是不能被響應式處理的。
如何解決?
//祖組件
<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 ?//此時是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變成一個箭頭函數(shù)。然后在孫頁面通過執(zhí)行這個函數(shù)的方式拿到函數(shù)返回的結果就可以拿到最新的值。也就間接變成了響應式的了
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
解決Vue警告Write?operation?failed:computed?value?is?readonl
這篇文章主要給大家介紹了關于如何解決Vue警告Write?operation?failed:computed?value?is?readonly的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-03-03
vue實現(xiàn)多個echarts根據(jù)屏幕大小變化而變化實例
這篇文章主要介紹了vue實現(xiàn)多個echarts根據(jù)屏幕大小變化而變化實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07

