Vue3 中 echarts resize() 不生效

背景

最近在用 Vue3 开发一个可视化页面时发生了个奇怪的现象,想实现图表在用户调整窗口大小后重新渲染,防止发生变形,已经在元素上设置了百分比宽高,但它就是不生效。

解决方案

不多废话,先说解决方案。其实很简单,只需要将你的 echarts 实例对象用 shadowRef() 进行创建,而不是使用坑人的 ref()

原来的写法

js 复制代码
import * as echarts from 'echarts';
import { onMounted, ref } from 'vue';

// !!!重点就在这里!!!
const chart = ref(null);

onMounted(() => {
  initChart();
  // 添加窗口大小变化监听
  window.addEventListener('resize', handleResize);
});

const initChart = () => {
	const options = { .....};
	const chartDom = document.getElementById('chart');
    chart.value = echarts.init(chartDom);
    chart.value.setOption(options);
  }
}

// 处理窗口大小变化
const handleResize = () => {
  chart.value && chart.value.resize();
};

修复后写法

js 复制代码
......保持不变
import { onMounted, shadowRef } from 'vue';

// !!!重点就在这里!!!
const chart = shadowRef(null);
...保持不变

寻找原因

改完之后生效并且不想关注原因的兄弟可以关闭网站继续搬砖了。

元素宽高百分比?

刚开始我从网上找到的解决方案都是围绕在 echarts 所在元素不能设置固定宽高这个问题上,我的写法确实也不对,但是我将宽高改成百分比之后还是不行,并且在浏览器控制台发现了一个奇怪的报错: echart.resize LineView seriesModel.coordinateSystem undefined

coordinateSystem?

基于这个关键词,我又找到了 echarts Github 仓库的 issues 列表里,在这里找到了我们最终的解决方案,感谢这位大善人🙏。

github.com/apache/echa...

shadowRef ?

这又是个什么 API?我怎么没学过?

既然遇到了,那就学学吧。

shallowRef 在 Vue 3 中用于创建一个 Ref 对象,但是它不会将对象内部的属性进行深层响应式化。这意味着,当对象本身被替换时,shallowRef 会触发更新,但对象内部的属性发生变化时不会触发更新。 使用场景:

  1. 性能优化: 对于大型对象,尤其是在对象内部的属性变化不应该影响视图更新的情况下,使用 shallowRef 可以提高性能,减少不必要的更新。
  2. 与第三方库集成: 当你需要将第三方库的对象暴露给组件,并且第三方库的API可能导致对象内部的属性变化,但你不需要让组件对这些变化进行响应时,shallowRef 可以帮助你避免不必要的更新和性能问题。
  3. 临时读取: 当你只需要临时读取某个对象的数据,而不需要对这个对象进行响应式跟踪时,shallowRef 可以避免不必要的跟踪开销。

shadowRef 与 ref 的区别:

  • ref 会将对象内部的属性进行深层响应式化,即对象内部任何属性的改变都会导致视图更新。
  • shallowRef 只对对象本身进行响应式化,对象内部的属性变化不会触发视图更新。

个人理解可能是 ref 的深层响应化破坏或影响了 echarts 对象本身,从而导致 echarts 实例中的某些方法失效。

总结

刚才我说 ref 坑人其实有失偏颇,大家还是要根据使用场景来选择到底要用哪个 API,显然这个场景下 shadowRef 是好用的。

Vue3,你就学吧~

相关推荐
清幽竹客7 小时前
vue-30(理解 Nuxt.js 目录结构)
前端·javascript·vue.js
知性的小mahua7 小时前
echarts+vue实现中国地图板块渲染+省市区跳转渲染
vue.js
weiweiweb8887 小时前
cesium加载Draco几何压缩数据
前端·javascript·vue.js
满楼、9 天前
el-cascader 设置可以手动输入也可以下拉选择
javascript·vue.js·elementui
前端fighter9 天前
Vuex 与 Pinia:全面解析现代 Vue 状态管理的进化之路
前端·vue.js·面试
snow@li9 天前
vue3-ts-qrcode :安装及使用记录 / 配置项 / 效果展示
前端·javascript·vue.js
海天胜景9 天前
vue3 el-table 根据字段值 改变整行字体颜色
javascript·vue.js·elementui
萌萌哒草头将军9 天前
什么?React 中可以写 SolidJS 了?SolidJS 官方出手了 🚀🚀🚀
前端·vue.js·react.js
Kier10 天前
🔋 Vue + ECharts 实现分段折线图教学实战:电池趋势图案例
前端·javascript·echarts
用户38022585982410 天前
vue3源码解析:diff算法之节点类型处理机制分析
前端·vue.js