vue中provide和inject的用法及说明(vue组件爷孙传值)

 更新时间:2023年05月17日 10:21:30   作者:是小橙鸭丶  
这篇文章主要介绍了vue中provide和inject的用法及说明(vue组件爷孙传值),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

provide和inject的用法(vue组件爷孙传值)

聊聊概念

成对出现:provide和inject是成对出现的

作用:用于父组件向子孙组件传递数据

使用方法:provide在父组件中返回要传给下级的数据,inject在需要使用这个数据的子辈组件或者孙辈等下级组件中注入数据。

使用场景:由于vue有$parent属性可以让子组件访问父组件。但孙组件想要访问祖先组件就比较困难。通过provide/inject可以轻松实现跨级访问父组件的数据

使用示例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是一个匿名函数,返回一个对象
		return {
			testmethods:this.testmethods,
			message:this.message
		}
	},
	methods:{
		testmethods(){
			console.log('调用了ProvideTest这个组件')
		}
	},
	components:{
		second
	}
}
</script>
<style lang="less" scoped>
</style>

子组件:用inject接收父组件的值和方法,并且继续套一个组件

<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可以跨层传递。但是最近在使用的过程中发现一个问题:

祖组件中data里的响应式数据通过provide return以后,发现孙组件无法接受到最新的值

//祖组件
<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经过异步请求以后变成了true,原本期待provide最后return的值是最新的值时true,结果在孙组件页面打印this.hasMeal发现。

还是false?那是否是provide在return之前的this.hasMeal还是false呢?

经过测试发现,果不其然。进一步证明。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变成一个箭头函数。然后在孙页面通过执行这个函数的方式拿到函数返回的结果就可以拿到最新的值。也就间接变成了响应式的了 

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue-cli3.0之配置productionGzip方式

    vue-cli3.0之配置productionGzip方式

    这篇文章主要介绍了vue-cli3.0之配置productionGzip方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • element-plus中el-table点击单行修改背景色方法

    element-plus中el-table点击单行修改背景色方法

    这篇文章主要给大家介绍了关于element-plus中el-table点击单行修改背景色的相关资料,这是产品新加了的一个需求,分享给同样遇到这个需求的朋友,需要的朋友可以参考下
    2023-07-07
  • 解决vue prop传值default属性如何使用,为何不生效的问题

    解决vue prop传值default属性如何使用,为何不生效的问题

    这篇文章主要介绍了解决vue prop传值default属性如何使用,为何不生效的问题。具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 使用vue导出excel遇到的坑及解决

    使用vue导出excel遇到的坑及解决

    这篇文章主要介绍了使用vue导出excel遇到的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • VUE解决微信签名及SPA微信invalid signature问题(完美处理)

    VUE解决微信签名及SPA微信invalid signature问题(完美处理)

    这篇文章主要介绍了VUE解决微信签名及SPA微信invalid signature问题(完美处理),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • Vue3 watchEffect的使用教程和相关概念

    Vue3 watchEffect的使用教程和相关概念

    Vue 3 引入了 Composition API,其中 watchEffect 是一个非常强大的工具,用于响应式地追踪依赖项的变化,本文将详细介绍 watchEffect 的使用方法和相关概念,文中有详细的代码供大家参考,需要的朋友可以参考下
    2024-08-08
  • vue如何动态加载组件详解

    vue如何动态加载组件详解

    组件是Vue.js最强大的功能之一,组件可以扩展HTML元素,封装可重用的代码,下面这篇文章主要给大家介绍了关于vue如何动态加载组件的相关资料,需要的朋友可以参考下
    2022-10-10
  • Vue拖拽组件列表实现动态页面配置功能

    Vue拖拽组件列表实现动态页面配置功能

    这篇文章主要介绍了Vue拖拽组件列表实现动态页面配置功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-06-06
  • Electron + vue 打包桌面操作流程详解

    Electron + vue 打包桌面操作流程详解

    这篇文章主要介绍了Electron + vue 打包桌面操作流程,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-06-06
  • 解决betterScroll在vue中存在图片时,出现拉不动的问题

    解决betterScroll在vue中存在图片时,出现拉不动的问题

    今天小编就为大家分享一篇解决betterScroll在vue中存在图片时,出现拉不动的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09

最新评论