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,你就学吧~

相关推荐
killerbasd5 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
大家的林语冰6 小时前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js
M ? A8 小时前
Vue 迁移 React 实战:VuReact 一键自动化转换方案
前端·vue.js·经验分享·react.js·开源·自动化·vureact
Burt8 小时前
我的 2026 全栈选型:Vue3 + Elysia + Bun + AlovaJS
vue.js·全栈·bun
小锋java12349 小时前
SpringBoot 4 + Spring Security 7 + Vue3 前后端分离项目设计最佳实践
java·vue.js·spring boot
一 乐9 小时前
校园线上招聘|基于springboot + vue校园线上招聘系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·校园线上招聘系统
LanceJiang9 小时前
从输入 URL 到页面:一个 Vue 项目的“奇幻漂流”
vue.js
码喽7号10 小时前
vue学习四:Axios网络请求
前端·vue.js·学习
像素之间11 小时前
为什么运行时要加set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve
前端·javascript·vue.js
M ? A11 小时前
Vue转React实战:defineProps精准迁移实战
前端·javascript·vue.js·经验分享·react.js·开源·vureact