问题再现
后台管理页面,首页是echarts可视化大屏,里面全是图表。第一次在刚打开这个页面的时候,是可以正常显示的。从这个页面跳转到其他页面,再从其他页面跳转回首页,就不显示了,除了空白的骨架屏,什么数据和图表都没有。
问题如下:
这究竟是什么原因呢?
尝试
我开始进行三个假设,尝试去解决这个问题
第一个尝试:
我猜测可能是代码出了问题,于是我将页面的7个echarts图表全部关闭。逐一打开图表排查。
结果:
单独将任何一个echarts图表打开,是可以来回跳转的,不会产生上面的问题。
打开图表1234 正常 缺567
打开图表12346正常 缺57
打开图表123456正常 缺7
打开图表123567 正常 缺4
打开图表4567 正常 缺123
这个bug太神奇了,简直是太神奇了, 如果按这种排列组合去测,7的排列组合会有n多种结果,我即使两天时间都找这个bug,但会有结果吗?
可如果真是某一个图表配置的有问题,或者某一行代码有问题,那么图表为什么在不同的组合下,能正常显示呢?
而且以我对echarts的配置还是比较自信的,代码当是没问题的。于是有了第二个尝试。
第二个尝试:
我猜测或许是声命周期的原因,我应该在每次跳转页面时,销毁掉之前的缓存,重新请求,重新加载。
可是试遍了生命周期,也没有找到原因。
我原本用的是onMount
生命周期,后来一想,从生命周期角度来说,这完全合理啊。
所有的接口请求,获取dom,图表配置,图表自适应,数据处理,全部在init
函数里。
整个页面也就是三部分,导入模块,一个函数,调用一下函数,有毛病吗?
于是我排除了这个可能,因为以前在做echarts这一块的时候,都是放在onMounted中,也没有出现过问题。
发现问题的第三个尝试
第三次尝试,才是真正发现问题。
在从不同页面切换到首页的时候,打开控制台,看警告和报错,有何变化,如果有变化,看看这个变化到底是什么意思,是否合理。
在初次加载首页时,dom是什么样的。从其他页面跳转回首页时,dom是否有变化。
经过这样不断的测试,找到了原因:
警告报错层面:
倒是没有报错,但有一个警告:
7个表,刚好七个警告:
因为已经初始化了,所以不加载了是吗?
dom层面:
_echarts_instance_="ec_1692148152640"
这是个什么东西,我什么时候给dom加这个属性了?
而且属性后面还有一堆数字作为属性值。
查看并研究才发现:
_echarts_instance_
是一个用于标识 ECharts 实例的变量名称,通常在使用 ECharts进行图表绘制时会生成。通过给实例变量赋予不同的值,可以同时管理多个 ECharts
实例。例如,在一个项目中可能存在多个图表,每个图表都有对应的 ECharts 实例,使用不同的变量名进行区分。
简而言之,这相当于每个图表的一个唯一标识。每次图表创建时,就会生成这个东西。
也就是说,在首页加载成功时,这个东西就已经生成了,当我从其他页面跳转到首页时,这个东西还在。
所以就有了上面的警告:There is a chart instance already initialized on the dom.
那么也就是说,只要删除掉这个属性,那么每次dom都会重新挂载,在切换页面时首页就可以正常显示了。
解决问题
到这边,我开始在网上搜,删除_echarts_instance_
属性的方法,居然没想到有一大堆前辈已经遇到过这个问题,于是我直接将方法拿来用。
chart.removeAttribute('_echarts_instance_')
开始我是这样写的:
const myChart6 = echarts.init(document.querySelector("#leftbottomtwo")).removeAttribute("_echarts_instance_");
结果不中用,我写链式写习惯了,但这样是不行的,我很疑惑,这为什么就不可以,知道的大神评论区告诉我。
于是我就拆开写:
const chart6 = document.querySelector("#leftbottomtwo"); chart6.removeAttribute("_echarts_instance_"); const myChart6 = echarts.init(chart6);
然后就好了:
ok,到这也就结束了,问题有始有终。终于是给他干掉了,又是一个宝贵的经验。不遇到这些问题,就永远无法了解的更深。