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