1.旧代码:
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.加上定时器,报错
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()方法报错
3.修改为如下代码:(正确)
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()报错,所以应该只在首次入栈一次
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)
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。