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定义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传递的参数都能拿到,问题解决~。
总结
最近我经常用上面的方案二来解决类似的问题,把他分享给大家,并且如果有更好的方法或者我上面有什么说的不正确,也请大家多多指教。