vue中在echarts里設置的定時器清除不掉問題及解決
在echarts里設置的定時器清除不掉問題
在動態(tài)圖里,往往需要用到定時器去動態(tài)渲染數(shù)據(jù),
我的需求是:當x軸類目過多的時候,就讓它自動滾動,這個時候需要用到定時器去動態(tài)的控制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,發(fā)現(xiàn)怎么也清除不了這個定時器,現(xiàn)在講一下解決思路
造成這個bug的原因是:
因為要將后端返的數(shù)據(jù)賦值給柱形圖里series的data,我一開始采用的方式是,用watch監(jiān)聽返回的值,然后賦值給data,這樣做的目的是為了能夠渲染出圖形,如果直接賦值,圖形是不會生效的。
關鍵就在這個watch監(jiān)聽,因為我一直在監(jiān)聽,導致一直生成定時器,才使得用clearInterval也無法清除掉定時器,因為你即使清除了 它又立馬生成了一個新的定時器。
分析出問題所在,那我們就換一種方式去賦值,然后我采用了
在.then里使用this.$nextTick 去調用生成echarts圖形的函數(shù),也就是
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節(jié)點。 ? ? ? if (myChart == null) { ? ? ? ? // 如果不存在,就進行初始化。 ? ? ? ? myChart = that.$echarts.init(document.getElementById("productivity")); ? ? ? } ? ? var option={ ?? ??? ?//其他配置我就跳過不寫了 ?? ??? ?dataZoom: [ ? ? ? ? ? { ? ? ? ? ? ? type: "inside", //拖拽 slider 為滾動 ? ? ? ? ? ? xAxisIndex: 0, //控制第一個x軸 ? ? ? ? ? ? startValue: 0, ? ? ? ? ? ? endValue: that.xNum,//這個值是我動態(tài)設置顯示多少個柱形 ? ? ? ? ? ? show: true, ? ? ? ? ? }, ? ? ? ? ], ? ? ? ? series:{ ?? ??? ??? ?name: "綠燈", ? ? ? ? ? ? type: "bar", ? ? ? ? ? ? stack: "total", ? ? ? ? ? ? barMaxWidth: 50, ? ? ? ? ? ? data: this.barData,//后端返的柱形圖數(shù)據(jù) ? ? ? ? ? ? itemStyle: { ? ? ? ? ? ? ? normal: { color: "#14ee14" }, ? ? ? ? ? ? }, ?? ??? ?} ?? ?} ?? ?// 使用剛指定的配置項和數(shù)據(jù)顯示圖表。 ? ? ? 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)就能清除掉
整體就這么一個思路,其實解決起來也很簡單,只是換了一種動態(tài)賦值方式,關鍵是要分析正確導致問題的原因。
vue3定時+echarts的細節(jié)處理
1、如果在當前頁面停留時間久了會占滿內存導致圖表卡頓最后導致崩潰
2、當處理了占滿內存之后如果頁面切換不去點回去的過程中還是會崩潰
3、如果有多個圖表想進行關聯(lián)處理
4、當封裝一個組件使用echarts.getInstanceByDom類型不匹配處理
5、當瀏覽器窗口改變之后 圖表自適應之后會移位的問題
6、折線窗口如果數(shù)據(jù)數(shù)據(jù)過大導致起伏不明顯問題
// 查詢按鈕點擊事件 const search = () => { if (listParams.datePicker) { //如果是時間則取消自動刷新 clearInterval(time.value) getAllList() titleBegin.value = '開啟自動刷新' } else { getAllList() titleBegin.value = '關閉自動刷新' } } //監(jiān)聽數(shù)據(jù)并計時 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() } }) //數(shù)據(jù)值大導致起伏不明顯問題 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() } })
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
深入探討Vue3實現(xiàn)多數(shù)據(jù)變化監(jiān)聽的方式
隨著 Vue 3 的發(fā)布,框架帶來了更多的新特性和增強,其中之一就是 watch 函數(shù)的升級,這一改進使得多個數(shù)據(jù)的變化偵聽更加優(yōu)雅和靈活,本文將深入探討 Vue 3 中的 watch 函數(shù),以及如何以更加優(yōu)雅的方式實現(xiàn)對多個數(shù)據(jù)變化的監(jiān)聽2023-08-08Vue使用v-model收集各種表單數(shù)據(jù)、過濾器的示例詳解
這篇文章主要介紹了Vue使用v-model收集各種表單數(shù)據(jù)、過濾器的示例,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-08-08vue中實現(xiàn)監(jiān)聽數(shù)組內部元素
這篇文章主要介紹了vue中實現(xiàn)監(jiān)聽數(shù)組內部元素方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08