vue使用this.$bus+keep-alive解决组件间跳转传参,参数无法保存问题

vue使用this.$bus+keep-alive解决组件间跳转传参,参数无法保存问题

前言

这是我在最近工作中经常遇到的问题,整理一下分享一波,希望大家也少踩坑。

问题描述

组件a使用this.$router.push({name: '组件b',params: '参数1'})传递参数并跳转到组件b后,组件b用this.$route.param获取到参数1,组件b跳转到组件c,并携带参数2再跳转回组件b,此时发现this.$route只能拿到参数2,拿不到参数1了。
原因就是组件b跳转到组件c又跳转回组件b,此时可以看做刷新了一次。
this.$route.param传递参数一般只用于简单的单项传递,且不能刷新,一刷新参数就没啦。
在这里插入图片描述

解决方法一:使用Vuex

每当出现组件传参问题时,我总会第一时间想到Vuex,Vuex确实能解决此类问题,但vuex适合大型项目跨组件储存数据,若数据量不是很大,且有很多这种问题则vuex里会储存的很杂很乱不好维护。之前看到过一句话,Vuex什么时候用?当你觉得你的项目可用可不用的时候,那就不要用。
所以这里我选择了另一种方法来解决这个问题。

解决方法二:使用bus+keep-alive

bus就是广播一个方法,方法里可以携带参数,然后任意组件都可以监听这个广播的方法,需要时接收广播并获取参数。功能和this.$router.push类似,只不过一个是定向跳转,一个可以随时接收。

  • bus的基础使用方法

1.在main.js定义 b u s 使 t h i s . bus,之后使用就直接`this. bus`
在这里插入图片描述

2.组件c广播事件
第180行this.$bus.$emit('itemCode', item)就是广播,参数1是广播的事件名,参数2是携带的参数。
第181行是路由跳回上一个路由。因为是从组件b跳到组件c,所以这里是跳回组件b。
在这里插入图片描述

3.组件b监听事件并接收参数
监听要在mounted生命周期里进行
第79行this.$bus.$on('itemCode', (item) => { })参数1itemCode是监听的事件名,参数2是一个函数,函数的参数是事件携带的参数item,可在函数体力进行数据处理操作,用箭头函数是处理this指向问题。
这里要注意第78行this.$bus.off('itemCode')是取消监听事件itemCode,监听事件时一定要在监听之前先取消这个监听事件,否则会导致下次重复监听,函数体里的操作会被执行多次。
在这里插入图片描述

  • bus与keep-alive联用处理参数无法保存问题
    此方法会解决最开始问题描述中的问题。

1.根据问题描述可以知道,只有组件b要对组件a的参数缓存,所以将组件bFilterShop添加进keep-alive中。
include里可以放缓存多个页面
在这里插入图片描述

2.组件a跳转到组件b并携带参数
组件a广播了一个事件workShop并携带参数this.workInfo,紧接着又使用this.$router.push跳转到组件b并传递参数this.workInfo。为何要这样写的原因之后再说。
在这里插入图片描述
3.组件b监听组件a和组件c广播的事件,且用$this.route.params接收组件a的参数
因为组件b在keep-alive里缓存了,所以组件b的生命周期改变,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。
因为路由跳转的顺序是组件a -> 组件b -> 组件c -> 组件b,所以当组件a跳转到组件b时,拿不到监听组件a发出的方法的参数,所以组件a的参数要现在created里通过this.$route.params来获取,之后组件b跳转到组件c再跳转回来后,其他生命周期都不会触发,只触发activated钩子,此时的监听方法都会生效。所以组件a才需要写两种参数传递方法。
此时在组件b中,组件a和组件c传递的参数都能拿到,问题解决~。

在这里插入图片描述

总结

最近我经常用上面的方案二来解决类似的问题,把他分享给大家,并且如果有更好的方法或者我上面有什么说的不正确,也请大家多多指教。