resize.js
import {nextTick, ref} from "vue";
import {debounce} from 'throttle-debounce';
/*chart 是echarts图的实例*/
export const chart = ref();
/*检测侧边栏是否缩放*/
let sidebarElm;
/*使用element-resize-detector 来监听侧边栏是否产生变化*/
const elementResizeDetectorMaker = require("element-resize-detector");
const erd = elementResizeDetectorMaker();
/*使用防抖debounce函数,减少resize的次数*/
const chartResizeHandler = debounce(100, false, () => {
if (chart.value) {
chart.value.resize()
}
})
/*在侧边栏宽度变化后,执行该函数*/
const sidebarResizeHandler = (e) => {
nextTick(() => {
chartResizeHandler()
})
}
/*添加窗口大小变化监听*/
const initResizeEvent = () => {
window.addEventListener('resize', chartResizeHandler)
}
/*移除窗口大小变化监听*/
const destroyResizeEvent = () => {
window.removeEventListener('resize', chartResizeHandler)
}
/*初始化 sider监听*/
const initSidebarResizeEvent = () => {
/*获取侧边栏的document*/
sidebarElm = document.getElementsByClassName('sider-content')[0];
if (sidebarElm) {
erd.listenTo(sidebarElm, sidebarResizeHandler)
}
}
/*移除 sider监听*/
const destroySidebarResizeEvent = () => {
if (sidebarElm) {
erd.removeListener(sidebarElm)
}
}
export const mounted = () => {
initResizeEvent();
initSidebarResizeEvent();
}
export const beforeDestroy = () => {
destroyResizeEvent();
destroySidebarResizeEvent();
}
实际使用:
导入包
element-resize-detector
安装 npm install element-resize-detector --save
throttle-debounce
安装 npm install throttle-debounce --save
介绍一下 throttle
和 debounce
,它们都可以用于 函数节流 从而提升性能,但它们还是存在一些不同:
虽然每天最烦等电梯要花上十几分钟,但还是可以用坐电梯来举例子:
从上面两个例子中可以看出两者最大的区别在于只要有事件发生(有人想坐电梯),若使用了 throttle
方法,那么在一段时间内事件响应函数一定会执行(30秒内我按下关门键);若使用了 debounce
方法,那么只有事件停止发生后(我发现没有人想坐电梯)才会执行。
throttle
限制回调函数的执行频率
/**
* 节流(限制函数的执行频率)
* @param delay 延迟的时间
* @param noTrailing 在最后一次调用时是否执行 callback,true 不执行,false 执行
* @param callback 目标回调函数
* @param debounceMode
*/
throttle(delay, noTrailing, callback, debounceMode)
dobounceMode:
为 true 时,在被调用时,先执行 callback,在没有被调用时,在指定的延迟之后执行 clear,如果在clear 执行之前继续调用,会重置定时器;
为 false 时,在被调用时,不会执行 callback,在指定的延迟之后执行 callback,如果在 callback 执行之前继续调用,会重置定时器
debounce
限制回掉函数的执行频率,但是不同于 debounce 的是,debounce 能保证在一系列调用的时间内,回调函数只执行一次
/**
* 去抖(限制函数的执行频率)
* @param delay 延迟的时间
* @param atBegin
* @param callback 目标回调函数
*/
debounce(delay, atBegin, callback)
atBegin:
为 true 时,在被调用时,会马上执行 callback,如果在延迟时间之前继续调用,不会执行 callback;
为 false 时,在被调用时,不会执行 callback,在延迟时间之后会执行 callback,如果在延迟时间之前继续调用,会重置定时器
问题: 一个页面出现两个echarts图,会导致只有一个生效!
修改resize.js
import {nextTick, ref} from "vue";
import {debounce} from 'throttle-debounce';
export default function () {
const chart = ref();
let sidebarElm;
const elementResizeDetectorMaker = require("element-resize-detector");
const erd = elementResizeDetectorMaker();
const chartResizeHandler = debounce(100, false, () => {
if (chart.value) {
chart.value.resize()
}
})
const sidebarResizeHandler = (e) => {
nextTick(() => {
chartResizeHandler()
})
}
const initResizeEvent = () => {
window.addEventListener('resize', chartResizeHandler)
}
const destroyResizeEvent = () => {
window.removeEventListener('resize', chartResizeHandler)
}
const initSidebarResizeEvent = () => {
sidebarElm = document.getElementsByClassName('sider-content')[0];
if (sidebarElm) {
erd.listenTo(sidebarElm, sidebarResizeHandler)
}
}
const destroySidebarResizeEvent = () => {
if (sidebarElm) {
erd.removeListener(sidebarElm)
}
}
const mounted = () => {
initResizeEvent();
initSidebarResizeEvent();
}
const beforeDestroy = () => {
destroyResizeEvent();
destroySidebarResizeEvent();
}
return {
chart,
mounted,
beforeDestroy,
}
}
使用