vue中在echarts里设置的定时器清除不掉问题及解决
作者:听听那晚风
这篇文章主要介绍了vue中在echarts里设置的定时器清除不掉问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
在echarts里设置的定时器清除不掉问题
在动态图里,往往需要用到定时器去动态渲染数据,
我的需求是:当x轴类目过多的时候,就让它自动滚动,这个时候需要用到定时器去动态的控制dataZoom里endValue的值,
this.barInter = setInterval(() => { // 每次向后滚动一个,最后一个从头开始。 // console.log(this.xNum) if (option.dataZoom[0].endValue >= option.series[0].data.length) { option.dataZoom[0].endValue = that.xNum; option.dataZoom[0].startValue = 0; } else { option.dataZoom[0].endValue = option.dataZoom[0].endValue + that.xNum; option.dataZoom[0].startValue = option.dataZoom[0].startValue + that.xNum; } myChart.setOption(option); }, 1000);
然后我就遇到一个bug,发现怎么也清除不了这个定时器,现在讲一下解决思路
造成这个bug的原因是:
因为要将后端返的数据赋值给柱形图里series的data,我一开始采用的方式是,用watch监听返回的值,然后赋值给data,这样做的目的是为了能够渲染出图形,如果直接赋值,图形是不会生效的。
关键就在这个watch监听,因为我一直在监听,导致一直生成定时器,才使得用clearInterval也无法清除掉定时器,因为你即使清除了 它又立马生成了一个新的定时器。
分析出问题所在,那我们就换一种方式去赋值,然后我采用了
在.then里使用this.$nextTick 去调用生成echarts图形的函数,也就是
getData(){ this.$axios.selectEfficiencyExhibition(data).then((res) => { // console.log("设备OEE"); // console.log(res.data.data); if (res.data.data) { this.barData=res.data.data this.$nextTick(()=>{ this.barChart() }) } }) } barChart(){ let myChart = that.$echarts.getInstanceByDom( document.getElementById("productivity") ); //有的话就获取已有echarts实例的DOM节点。 if (myChart == null) { // 如果不存在,就进行初始化。 myChart = that.$echarts.init(document.getElementById("productivity")); } var option={ //其他配置我就跳过不写了 dataZoom: [ { type: "inside", //拖拽 slider 为滚动 xAxisIndex: 0, //控制第一个x轴 startValue: 0, endValue: that.xNum,//这个值是我动态设置显示多少个柱形 show: true, }, ], series:{ name: "绿灯", type: "bar", stack: "total", barMaxWidth: 50, data: this.barData,//后端返的柱形图数据 itemStyle: { normal: { color: "#14ee14" }, }, } } // 使用刚指定的配置项和数据显示图表。 this.barInter = setInterval(() => { // 每次向后滚动一个,最后一个从头开始。 if (option.dataZoom[0].endValue >= option.series.data.length) { option.dataZoom[0].endValue = this.xNum; option.dataZoom[0].startValue = 0; } else { option.dataZoom[0].endValue = option.dataZoom[0].endValue + 1; option.dataZoom[0].startValue = option.dataZoom[0].startValue + 1; } myChart.setOption(option); }, 1000); }
采用这种方式后,就不会一直生成定时器了,直接用clearInterval(this.barInter)就能清除掉
整体就这么一个思路,其实解决起来也很简单,只是换了一种动态赋值方式,关键是要分析正确导致问题的原因。
vue3定时+echarts的细节处理
1、如果在当前页面停留时间久了会占满内存导致图表卡顿最后导致崩溃
2、当处理了占满内存之后如果页面切换不去点回去的过程中还是会崩溃
3、如果有多个图表想进行关联处理
4、当封装一个组件使用echarts.getInstanceByDom类型不匹配处理
5、当浏览器窗口改变之后 图表自适应之后会移位的问题
6、折线窗口如果数据数据过大导致起伏不明显问题
// 查询按钮点击事件 const search = () => { if (listParams.datePicker) { //如果是时间则取消自动刷新 clearInterval(time.value) getAllList() titleBegin.value = '开启自动刷新' } else { getAllList() titleBegin.value = '关闭自动刷新' } } //监听数据并计时 watch( () => chartAvgCostData.value, (newVal) => { if (!listParams.datePicker) { clearInterval(time.value) timeOut() } } ) //累计计时的方法 const timeOut = () => { time.value = setInterval(() => { getAllList() }, 1000 * 20) } //清空定时器效果 onUnmounted(() => { clearInterval(time.value) }) // 需要在切换到其他页面时停止自动刷新,切回来时再开启 document.addEventListener('visibilitychange', () => { if ( !listParams.projectName && Object.keys(chartAvgCostData.value).length > 0 ) { return } if (document.hidden) { // 清除定时任务 clearInterval(time.value) time.value = null } else { // 开启定时任务 getAllList() } }) //数据值大导致起伏不明显问题 yAxis: { min: function (value:any) { // 取最小值向下取整为最小刻度 return 0 }, // 设置y轴最大值 max: function (value:any) { // 取最大值向上取整为最大刻度 return Math.floor(value.max + (Math.floor(value.max / 4))) }, } series:[ markPoint: { data: [ { type: 'max', name: 'Max' }, { type: 'min', name: 'Min' } ] }, ] //组件初次进来或者销毁清空图表 onMounted(() => { nextTick(() => { let myChart = echarts.getInstanceByDom(document.getElementById(myCanvas.value)!) if (myChart) { myChart.clear() } if (myChart === undefined) { myChart = echarts.init(document.getElementById(myCanvas.value) as HTMLElement) myChart.group = 'group1' myChart.setOption(datas.option) echarts.connect('group1') window.addEventListener('resize', () => { setTimeout(() => { myChart?.resize() }, 300) }) // 自适应屏幕 } }) }) onBeforeUnmount(() => { const myChart = echarts.getInstanceByDom(document.getElementById(myCanvas.value)!) if (myChart) { myChart.clear() } })
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。