Vue 组件之间事件触发($emit)和event bus事件监听($on)

在最近上线的一个项目中有个问题需要优化,首页总览页有个20秒的定时刷新时,每个列表数据里的detail页也要随之刷新即保持外层和内层的数据同步。由于当时开发为了组件化,列表页之间隔开了多个组件,所以总览刷新页和detail页不是父子组件也不是兄弟组件而是不相关的两个组件。由于总览页数据不是存放在vuex中,使用vuex控制事件的想法也被抛弃,后面我就想到通过bus事件车去作为组件之间的媒介进行监听和 触发事件,废话不多说,下面直接上代码。
首先让我们看下原效果

image.png

可以发现展开detail的时候总览页刷新并不会同时刷新detail页,这造成了外层数据是最新的但是展开的那一层detail里的数据是20秒之前的数据,不是同步最新的数据,会有问题。下面让我们开始解决这个问题!!
首先新建bus.js
image.png

import Vue from 'vue'

export default new Vue;

在refresh事件的组件中引入bus.js

import Bus from './bus.js'

在refresh接口请求中定义refresh事件

const data = {
        gid: this.gid,
        groupId: this.groupId,
        minerIds
      }
      getGpuRefresh(data).then(response => {
        //定义Bus触发事件
        Bus.$emit('refresh')
        const list = response.list
        list.forEach(item => {
          this.items.forEach(item2 => {
            if (item.minerId === item2.minerId) {
              item2 = Object.assign(item2, item)
            }
          })
        })
        // this.items.splice(start, response.list.length, ...response.list)
        this.time = 20
      })

同时在detail页引入bus.js

import Bus from '../bus.js'

展开detail页时监听refresh接口请求,如果请求就再次刷新detail页,通过以下代码

//利用Bus事件车监听总览页刷新事件,触发的同时刷新当前detail接口
        Bus.$on('refresh', () => {
          this.fetchDetail()
        })

按照以上方法其实已经实现了我们需要的逻辑,但是在测试中我发现监听会一直存在,大致意思就是你展开不同的detail页等待refresh时他会请求多个之前已经打开过得detail接口,这就给浏览器增加了较大的压力。
经过代码的重新优化,发现需要在下一次监听refresh事件前关闭监听,代码如下

//解决多次触发监听事件的问题,应先关闭再进行监听
        Bus.$off('refresh')
        //利用Bus事件车监听总览页刷新事件,触发的同时刷新当前detail接口
        Bus.$on('refresh', () => {
          this.fetchDetail()
        })

最后成功解决问题 ,效果如下图


效果图

你可能感兴趣的:(Vue 组件之间事件触发($emit)和event bus事件监听($on))