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 分钟前
Vue3 PC端 UI组件库我更推荐Naive UI
前端·vue.js·ui
述雾学java7 分钟前
Vue 生命周期详解(重点:mounted)
前端·javascript·vue.js
洛千陨13 分钟前
Vue实现悬浮图片弹出大图预览弹窗,弹窗顶部与图片顶部平齐
前端·vue.js
独立开阀者_FwtCoder28 分钟前
Node.js 官方发布新工具,助力稳定 TypeScript 支持!
前端·javascript·vue.js
Hilaku1 小时前
用了三年 Vue,我终于理解为什么“组件设计”才是重灾区
前端·javascript·vue.js
HuYi_code1 小时前
制作一个多层表头的实现
前端·vue.js
ShareJasmine1 小时前
Vue将后端数据转成树形结构的方法
前端·vue.js
wh_xia_jun1 小时前
ref 应用于对象类型的一个案例
前端·javascript·vue.js
前端工作日常1 小时前
学习 Vue2 自动生成的发布说明如何人工润色
vue.js
光影少年1 小时前
vue2为什么不能检查数组的的变化,改怎样解决
前端·vue.js·vuex