前言
在项目中使用 ECharts 遇到了一些问题,包括图表不会随着窗口大小变化而变化,以及父组件向子组件传值时,ECharts 中的值不会被同步渲染等,因此写本博文进行记录;
博文中的所有代码全部收集在博主的 GitHub 仓库中,相关技术栈专栏如下:
快速上手 ECharts
在分析解决问题前,我们先复现一下情景。根据 ECharts 的官方文档,我们快速的在 Vue 中构建 ECharts 图表。
首先,根据官方文档的提示,在下载好的 ECharts 压缩包中提取 dist/echarts.js
放置在自己项目的目录下,并在项目中进行引用,代码如下所示:
1 | html复制代码<head> |
接着,为 ECharts 准备一个 DOM 容器,代码如下所示:
1 | html复制代码<div id="main" style="width: 100%; height:400px;"></div> |
最后,通过 echarts.init
方法初始化一个 ECharts 实例并通过 setOption
方法生成一个简单的柱状图,代码如下所示:
1 | html复制代码<script> |
运行结果:
图表自适应
在上述构建的场景中,图表并不会随着窗口大小的变化而变化,如下所示:
为了实现图表的窗口自适应功能,我们需要监听窗口的大小变化,并且同时调整图表的大小,代码如下所示:
1 | js复制代码mounted() { |
在上述代码中,autoResize
表示是否启动自适应功能,window.addEventListener('resize', this.resizeChart)
监听窗口的大小变化,如果窗口大小发生改变,则调用 resizeChart()
方法,resizeChart()
方法中使用了 ECharts 自带的调整图表大小的方法 resize()
;
运行结果:
不过眼尖的读者已经发现了,只是缩小了一点窗口的大小,该方法就被调用了85次,这对我们来说是没有必要的,因为我们不需要实时的去调整窗口大小,只需要在一定时间内完成调整即可,因此引入 loadsh
的防抖功能,代码如下所示:
1 | html复制代码<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script> |
1 | js复制代码methods: { |
运行结果:
除了使用 loadsh
的防抖功能来节约资源,提高性能之外,还可以在 Vue 实例被销毁之前,取消监控并销毁 ECharts 实例,代码如下所示:
1 | js复制代码beforeDestroy() { |
数据不渲染
在前面的内容中,我们成功地开发了一个适用于特定场景的 Echarts 图表组件。为了让这个组件更具普适性和扩展性,我们计划对其进行一些改进和优化。
首先,我们将 div
元素的属性改进成动态绑定的方式,代码如下:
1 | html复制代码<div :class="className" :style="{ height: height, width: width }"></div> |
然后,设置组件的 props
配置,这些 props
允许在父组件中给子组件传递数据,同时也为这些属性提供了默认值以防止属性未被传递时出现错误,代码如下:
1 | js复制代码props: { |
在上述代码中,父组件传入不同的 series
数值,可以动态的改变 ECharts 图表。
接着,我们开始构建父组件,代码如下:
1 | html复制代码<template> |
在上述代码中,通过 fetchData()
方法来获取需要渲染数据,这里的话使用 POSTMAN 来模拟后端服务器发送数据。
创建一个模拟服务器,设置 API 接口与响应数据:
对模拟服务器进行相关配置:
通过访问 API 接口来获取数据:
同时也能查看到请求日志:
在 Vue 中,我们通过 axios 来请求接口,代码如下所示:
1 | js复制代码fetchData() { |
然而出现了点问题,数据是请求到了,但是 ECharts 图表并没有渲染上:
我们在子组件中也打印一下相关数据,确认父组件的数据是否传递到子组件中,代码如下所示:
1 | js复制代码console.log('Child Data Before:', this.series) |
子组件也确实获取到了数据,那为什么图表不渲染数据呢?
这是因为,当父组件需要通过异步 AJAX 请求获取数据来设置子组件的 props
属性时,可能会遇到子组件渲染速度快于 AJAX 请求返回的情况。这种情况下,父组件在 created
或 mounted
生命周期钩子函数执行时,子组件可能已经开始渲染,但是尚未接收到通过 AJAX 请求获得的数据,因此只有默认的 props
值会被子组件使用。
可以通过在父子组件中打点来得知程序的运行情况:
1 | js复制代码// parent |
运行结果:
通过上述的运行结果可知,正如我们所预料的那样,由于父组件的 fetchData()
方法使用了异步请求,因此程序会一直执行下去,并不会因为没有获取到数据而阻塞,当子组件完成图表渲染 initChart()
后,父组件才请求到数据,因此才造成了子组件图表中的数据不渲染问题,子组件图表渲染时使用的数据是 props
中的默认值,即空数组。
那如何解决这个问题呢?其实很简单,我们只要监听对应的属性即可。
1 | js复制代码watch: { |
上述代码之所以监听的是 option
而不是 series
,是因为在初始化图表时已经进行了赋值 this.option.series = this.series;
,series
本身是 option
的属性,通过 deep: true
也可以监听到 series
发生变化,同时监听 option
还能监听到其他属性。
运行结果:
后记
以上就是 解决 ECharts 图表窗口自适应与数据不渲染问题 的所有内容了,希望本篇博文对大家有所帮助!欢迎大家持续关注我的博客,一起分享学习和成长的乐趣!✨
代码:
📝 上篇精讲:解决 swagger2 默认地址失效
💖 我是 𝓼𝓲𝓭𝓲𝓸𝓽,期待你的关注,创作不易,请多多支持;
👍 公众号:sidiot的技术驿站;
🔥 系列专栏:问题解决;前端大杂烩;Vue.js 打怪升级之路
本文转载自: 掘金