echartsResize.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. const DESIGN_WIDTH = 1920;
  2. export function px2echarts(px) {
  3. const scale = window.innerWidth / DESIGN_WIDTH;
  4. return Math.round(px * scale);
  5. }
  6. export default {
  7. data() {
  8. return {
  9. $_chart: null,
  10. $_resizeObserver: null // 替换原来的 resizeHandler
  11. };
  12. },
  13. mounted() {
  14. // 确保 DOM 完全渲染后再进行监听
  15. this.$nextTick(() => {
  16. this.$_initResizeObserver();
  17. });
  18. },
  19. beforeDestroy() {
  20. this.$_destroyResizeObserver();
  21. if (this.$_chart) {
  22. this.$_chart.dispose();
  23. this.$_chart = null;
  24. }
  25. },
  26. methods: {
  27. $_initResizeObserver() {
  28. // 【智能挂载点】:优先寻找 ref="chartRef" 的专属图表容器,如果没有,则退而求其次监听整个组件根节点 ($el)
  29. const targetDom = this.$refs.chartRef || this.$el;
  30. // 确保取到的是有效的 DOM 元素
  31. if (!targetDom || targetDom.nodeType !== 1) return;
  32. let timer = null;
  33. this.$_resizeObserver = new ResizeObserver(() => {
  34. // 使用防抖 (Debounce) 避免拖拽弹窗时触发过于频繁导致页面卡顿
  35. if (timer) clearTimeout(timer);
  36. timer = setTimeout(() => {
  37. // 结合 requestAnimationFrame,在浏览器下一次重绘前执行,动画更丝滑
  38. // 并且能有效避免 "ResizeObserver loop limit exceeded" 这种控制台红字报错
  39. requestAnimationFrame(() => {
  40. if (this.$_chart) {
  41. // 1. 强制 ECharts 重绘画布物理大小
  42. this.$_chart.resize();
  43. // 2. 如果组件内部写了 updateChart 方法,自动触发它!
  44. if (typeof this.updateChart === 'function') {
  45. this.updateChart();
  46. }
  47. }
  48. });
  49. }, 50); // 50ms 是兼顾拖拽流畅度和 CPU 性能的黄金时间
  50. });
  51. // 开始监听
  52. this.$_resizeObserver.observe(targetDom);
  53. },
  54. $_destroyResizeObserver() {
  55. if (this.$_resizeObserver) {
  56. this.$_resizeObserver.disconnect(); // 停止监听,释放内存
  57. this.$_resizeObserver = null;
  58. }
  59. }
  60. }
  61. };