转载于简书 原文连接: https://www.jianshu.com/p/fde...一开始的需求是这样子的,我为了实现两个页面组件之间的数据传递,假设我有页面A,点击页面A上的某一个按钮以后,页面会自动跳转到页面B,同时我但愿将页面A上的某一些参数携带过去给页面B。(我知道,小参数的时候能够经过路由的params或者query去传参数,或者大型数据能够用vuex来处理,很遗憾我到如今尚未作很大型的项目,因此尚未用过vuex,接下来会学习一下。)vue
而后我就想,这不就是不一样组件之间的数据传递问题而已吗?直接用bus
巴士事件来传递数据不就好了吗。因而,我就很愉快地进行了。关于vue中的eventbus的使用,我以前在一篇vue中的数据传递中有提到过。 。git先给大家看一下我一开始的代码:github
实现目标: 点击以后,bus emit事件,而后顺便跳转路由到/moneyRecord页面。
接下来就是在MoneyRecord页面中去on接收这个事件,而后接受参数。 // 这是页面A的内部触发bus事件的代码vuex
editList (index, date, item) { // 点击进入编辑的页面,须要传递的参数比较多。 console.log(index, date, item) bus.$emit('get', { item: item.type, date: date }) this.$router.replace({path: '/moneyRecord'}) } // moneyRecord页面 created () { //这里我将icon的list给保存下来了 bus.$on('get', this.myhandle) }, methods: { myhandle (val) { console.log(val, '这是从上个页面传递过来的参数') } }
就当我欣喜若狂的时候,以为本身只要在页面A触发了get事件,页面B中就会理所固然的接受了数据。然而,结果却不如人意,看一下下面的动图。主要是看“”这是从上个页面传来的数据这一行数据的输出次数状况来判断事件触发次数。“”学习
test.gif
不知道你有没有发现,就是我第一次进去list页面的时候,我随便点击一下list下的任何一个item,控制台没有输出。可是当我第二次再点击触发事件的时候,就会输出一个测试数据。再一次进去点击,就输出两个数据。。。依次增长了。(控制台上那个“这是从上个页面传来的数据”就是测试数据)测试因此,有两个问题。this
问题:code
问题1: 为何第一次触发的时候页面B中的on事件没有被触发 问题2:
为何后面再一次依次去触发的时候会出现,每一次都会发现好像以前的on事件分发都没有被撤销同样,致使每一次的事件触发执行愈来愈多。 解决router针对问题1
这个还得从vue的生命周期提及了,我先进行了测试,就是当从页面组件A跳转到页面组件B的时候,两个组件的生命周期分别是怎么样的,关于vue的生命周期具体每个时期作什么事情我就再也不赘述了,下面po一张vue生命周期的图。生命周期image.png 我本身作了实验来验证,这个页面跳转过程当中,这两个组件的生命周期的执行状况。
// 我分别在页面A和页面B中去添加如下代码: beforeCreate () { console.group('%c%s', 'color:red', 'beforeCreate 建立前状态===============组件2》') }, created () { console.group('%c%s', 'color:red', 'created 建立完毕状态===============组件2》') }, beforeMount () { console.group('%c%s', 'color:red', 'beforeMount 挂载前状态===============组件2》') }, mounted () { console.group('%c%s', 'color:red', 'mounted 挂载状态===============组件2》') }, beforeUpdate () { console.group('%c%s', 'color:red', 'beforeUpdate 更新前状态===============组件2》') }, updated () { console.group('%c%s', 'color:red', 'updated 更新状态===============组件2》') }, beforeDestroy () { console.group('%c%s', 'color:red', 'beforeDestroy 破前状态===============组件2》') }, destroyed () { console.group('%c%s', 'color:red', 'destroyed 破坏状态===============组件2》') } // 另一个组件的我就不放出来了
测试结果图:
test.gif
image.png
其实,能够经过结果清楚看到,当咱们还在页面A的时候,页面B还没生成,也就是页面B中的 created中所监听的来自于A中的事件尚未被触发。这个时候当你A中emit事件的时候,B实际上是没有监听到的。
再看一下,红色的是B页面组件,当你从页面A到页面B跳转的时候,发生了什么?首先是先B组件先created而后beforeMount接着A组件才被销毁,A组件才执行beforeDestory,以及destoryed.
因此,咱们能够把A页面组件中的emit事件写在beforeDestory中去。由于这个时候,B页面组件已经被created了,也就是咱们写的$on事件已经触发了
因此能够,在beforeDestory的时候,$emit事件。
// 修改一下A页面中的代码: // 这是原先的代码 editList (index, date, item) { // 点击进入编辑的页面,须要传递的参数比较多。 console.log(index, date, item) this.item = item.type this.date = date this.$router.replace({path: '/moneyRecord'}) } // 从新在data属性内部定义新的变量,来存储要传过去的数据;
而后:
beforeDestroy () { console.log(this.highlight, '这是今年的数据', this, '看看组件销毁以前会发生什么') bus.$emit('get', { item: this.item, date: this.date }) },
接下来。看一下修改以后的效果test.gif
能够看到,就是第一次点击list的时候,也就是第一次触发emit事件的时候,控制太就输出了,因此在beforeDestoryed去$emit是起到做用的,B页面组件也监听$on到了。可是,好像,就是事件的触发仍是会依次增长,就是控制台的输出每次都有所增长了。。。
解决: 看一下github上提出的。issue https://github.com/vuejs/vue/...
image.png 尤大大提出了如下解决:
image.png
就是说,这个$on事件是不会自动清楚销毁的,须要咱们手动来销毁。(不过我不太清楚这里的external bus 是什么意思,有大神能解答一下的吗,尤大大也提到若是是注册的是external bus 的时候须要清除)*因此。我在B组件页面中添加Bus.$off来关闭。代码以下:
// 在B组件页面中添加如下语句,在组件beforeDestory的时候销毁。
beforeDestroy () { bus.$off('get', this.myhandle) },
来看一下输出的结果t能够看到,控制台第一次进去的时候就有输出,并且输出的不会逐次增长
*固然,尤大大还说能够写一个mixin?我还不知道是什么?之后在研究一下。总结: 因此,若是想要用bus
来进行页面组件之间的数据传递,须要注意亮点,组件A$emit事件应在beforeDestory生命周期内。其次,组件B内的$on记得要销毁。提问时间:大家在实现页面组件之间的数据传递有什么好的方法吗?能够留言分享一下吗?有时候虽然也能够经过从后台获取,可是考虑到数据只有几个须要传的话,就没有必要去请求数据,我知道有的还有用vueX传递。还有呢?
做者:Katherine的小世界 连接:https://www.jianshu.com/p/fde... 來源:简书