我们当前项目的需求是,要实现的是dashboard的数据每隔5分钟自动更新一次。
为了不浪费每一次更新,减少对接口的访问呢,我在这基础的需求之上加上了一些限制。
1,在当前的窗口中,可视界面被隐藏的时候,定时器清零。再次回到该界面,定时器重新开始。
2,去往另外的窗口的时候,即目标窗口已经不是正在打开的那个了,定时器清零。再次进入再开启定时器。
代码部分如下:
html部分:给需要监听的UI加上ref属性(其实我是要监听引入进来的子组件—》拖拽小球的。但是将ref给到该子组件身上,触发可视界面的监听存在问题,有小伙伴知道的话,可以给我解答下)
js部分:
// 定时器
const timerRef = ref();
// div绑定的ref
const echartRef = ref();
// 判断窗口是否可见
const isVisible = ref<boolean>(true)
// 用于获取可视界面的记录,是否是开启的状态
let observer:any;
// 当前标签页中,可视界面隐藏时 停止执行
const handleIntersect = (entries:any, observer:any) => {
entries.forEach((entry:any) => {
console.log(entry.isIntersecting,'entry.isIntersecting',isVisible.value,'isVisible.value');
if (entry.isIntersecting && isVisible.value) {
// 元素进入视窗,默认刷新一次,如果init接口在请求的话,就不重复执行
isInitStart ? null : dashboardDataFuntion()
timerRef.value = setInterval(() => {
// 执行定时器逻辑 5分钟刷新一次 (15秒==15000)
dashboardDataFuntion();
},300000);
} else {
// 元素离开视窗
clearInterval(timerRef.value);
}
});
};
// 判断当前网页是否可见,不可见定时器也停止执行(优化性能)
const handleVisibilityChange = () => {
if (document.visibilityState === 'hidden') {
// 网页不可见,清除定时器
clearInterval(timerRef.value);
isVisible.value = false
observer.disconnect();
} else {
// 网页可见,重新启动定时器
isVisible.value = true
// 再次执行 handleIntersect
if(echartRef.value) observer.observe(echartRef.value);
else return
const entries = observer.takeRecords(); // 获取当前的 IntersectionObserver 记录
handleIntersect(entries, observer);
}
};
在页面初始化的时候挂载,在页面卸载的时候清除
onMounted(() => {
init()
observer = new IntersectionObserver(handleIntersect);
// 通过ref绑定的组件可视化的时候 执行定时请求接口
observer.observe(echartRef.value)
// 监听页面可见性状态变化
document.addEventListener('visibilitychange', handleVisibilityChange);
})
onUnmounted(()=>{
// 卸载时清除定时器功能,清除页面监听功能,清除可视区域监听功能
clearInterval(timerRef.value)
observer.disconnect();
window.removeEventListener('visibilitychange', handleVisibilityChange, true)
})