1.舊代碼:echarts
analyzeRadar().then(result => { if (res.code === 200) { this.setEcharts({ indicator: indicator, seriesData: seriesData }) } }
setEcharts (data) { const dom = this.$refs.echart let myChart = echarts.init(dom) const option = {…} myChart.setOption(option) this.$once('hook:beforeDestroy', () => { window.removeEventListener('resize', myChart.resize) myChart.clear() myChart.dispose() }) window.addEventListener('resize', myChart.resize) }
2.加上定時器,報錯dom
analyzeRadar().then(result => { if (res.code === 200) { this.setEcharts({ indicator: indicator, seriesData: seriesData }) this.timer = setTimeout(() => { this.getData() }, 5000) } }
緣由分析:一進入頁面,定時器執行一次,過了this.second * 1000s以後,定時器又執行一次,總共兩次,切換到其餘頁面,執行銷燬鉤子,清理第一個定時器正常,清理第二個的時候myChart在上一次已經被清理,爲undefined,執行clear()方法報錯this
3.修改成以下代碼:(正確)spa
setEcharts (data) { const dom = this.$refs.echart // echarts.getInstanceByDom(dom)只有init以後dom上纔會有echart實例,不然爲undefined,即第一次進入,那麼才進行初始化,第二次以後dom上就有echart實例了,就不用初始化,能夠直接setOption構圖了 let myChart = echarts.getInstanceByDom(dom) // 獲取 dom 容器上的實例。 if (!myChart) { // 若不存在則代表是首次加載組件,需初始化 myChart = echarts.init(dom) // 跟if觸發無關,只是爲了首次進入使用mychart不會報錯,觸發條件是一離開頁面就觸發 this.$once('hook:beforeDestroy', () => { // 只會在首次的時候入棧一個 clearTimeout(this.timer) window.removeEventListener('resize', myChart.resize) myChart.clear() myChart.dispose() }) window.addEventListener('resize', myChart.resize) } const option = {…} myChart.setOption(option) } }
4.如下想法是錯誤的:hook:beforeDestroy執行的次數與定時器執行的次數相同,myChart.clear()沒問題,第二次就undefined.clear()報錯,因此應該只在首次入棧一次code
if (!myChart) { // 若不存在則代表是首次加載組件,需初始化 myChart = echarts.init(dom) } else { // 有myChart纔去清,報錯 this.$once('hook:beforeDestroy', () => { // 定時次執行幾回,它就入棧幾回,最終銷燬的時候執行幾回 clearTimeout(this.timer) window.removeEventListener('resize', myChart.resize) myChart.clear() myChart.dispose() }) window.addEventListener('resize', myChart.resize) }