You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3+Gridstack响应式仪表盘:组件无法随部件Resize问题求助

Vue3 + Gridstack JS:部件尺寸调整时内部ECharts/Bootstrap表格无法自适应的解决方案

问题根源

你当前用window.addEventListener('resize')的方式只监听了浏览器窗口的大小变化,但Gridstack调整部件尺寸时,浏览器窗口本身并没有改变,所以这个事件不会触发。内部的ECharts和Bootstrap表格自然不会跟着调整尺寸。


具体解决方案

1. 监听Gridstack自带的部件resize事件

Gridstack提供了专门的resize事件,用于监听单个部件的尺寸变化,这才是适配你场景的正确触发源。

import { ref, onMounted } from 'vue';
import GridStack from 'gridstack';

export default {
  setup() {
    const grid = ref(null);
    const chartInstance = ref(null); // 存储ECharts实例

    onMounted(() => {
      // 初始化Gridstack
      grid.value = GridStack.init({
        container: '#grid-container',
        // 你的Gridstack配置项
      });

      // 绑定部件resize事件
      grid.value.on('resize', (event, widget) => {
        // 定位当前部件内的ECharts容器
        const chartDom = widget.el.querySelector('.echarts-container');
        if (chartDom && chartInstance.value) {
          // ECharts自带resize方法,会自动读取容器当前尺寸
          chartInstance.value.resize();
        }

        // Bootstrap表格适配:模拟窗口resize事件触发表格自适应,或直接调用表格刷新方法
        // 示例(Bootstrap Table):
        // const tableEl = widget.el.querySelector('.table');
        // if (tableEl) {
        //   $(tableEl).bootstrapTable('refreshOptions', { height: widget.el.clientHeight - 40 });
        // }
        // 或者简单触发全局resize事件(适合依赖window.resize的组件):
        window.dispatchEvent(new Event('resize'));
      });
    });

    return { grid, chartInstance };
  }
};

2. 优化ECharts的自适应逻辑

放弃用window.innerWidth/innerHeight传递尺寸,让ECharts直接读取自身容器的尺寸——毕竟部件内的容器尺寸才是它真正需要的,和窗口尺寸无关。

修改你的ECharts初始化代码:

// 假设用ref绑定ECharts容器
const chartDom = ref(null);
chartInstance.value = echarts.init(chartDom.value);
chartInstance.value.setOption(options);

// 移除原有的window.resize监听,改用Gridstack的resize事件触发

3. 封装可复用的部件组件

把带自适应逻辑的部件封装成独立Vue组件,方便管理和复用:

<template>
  <div class="grid-stack-item-content">
    <div ref="chartDom" class="echarts-container"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import * as echarts from 'echarts';

const props = defineProps({
  widgetId: { type: String, required: true },
  chartOptions: { type: Object, required: true }
});

const chartDom = ref(null);
let chart = null;
let gridInstance = null;

onMounted(() => {
  // 获取全局或父组件传递的Gridstack实例
  gridInstance = window.gridStack;
  chart = echarts.init(chartDom.value);
  chart.setOption(props.chartOptions);

  // 只监听当前部件的resize事件
  gridInstance.on('resize', (event, widget) => {
    if (widget.id === props.widgetId) {
      chart.resize();
    }
  });
});

onUnmounted(() => {
  // 清理事件监听和实例,避免内存泄漏
  if (gridInstance) gridInstance.off('resize');
  if (chart) chart.dispose();
});
</script>

<style scoped>
.echarts-container {
  width: 100%;
  height: 100%;
}
</style>

关键注意事项

  • 部件内的ECharts/表格容器必须设置width: 100%; height: 100%;,确保能继承部件的尺寸。
  • 组件卸载时记得移除Gridstack的事件监听,避免内存泄漏。
  • 不要依赖window.resize处理部件内的组件自适应,Gridstack自身的事件才是精准触发源。

内容的提问来源于stack exchange,提问作者JDGab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 20:49:54