在Vue3中使?echarts?圖表寬度自適應(yīng)變化的操作方法
需求:
有現(xiàn)在這樣一段使用 echarts 的 vue3 代碼:
<template>
<div ref="chartRef" style="width: 600px; height: 400px;"></div>
</template>
<script setup>
import {getCurrentInstance, onMounted, onUnmounted, ref} from 'vue';
const chartRef = ref(null);
let chartInstance = null;
// 通過 getCurrentInstance 訪問全局屬性
const {proxy} = getCurrentInstance();
onMounted(() => {
chartInstance = proxy.$echarts.init(chartRef.value);
chartInstance.setOption({
title: {text: '柱狀圖示例'},
tooltip: {},
xAxis: {data: ['A', 'B', 'C', 'D', 'E']},
yAxis: {},
series: [{type: 'bar', data: [10, 20, 30, 40, 50]}]
});
});
onUnmounted(() => {
chartInstance?.dispose(); // 銷毀實(shí)例
});
</script>作用是在界面顯示一個柱狀圖:

問題是在頁面縮放時,圖表大小始終固定:

希望圖表能夠根據(jù)頁面寬度自動調(diào)整,特別是在頁面縮放時。
解決:
在代碼中,chartRef的div被固定設(shè)置為600px寬和400px高,現(xiàn)在需要修改這部分,讓圖表始終占據(jù)頁面的寬度,并能夠響應(yīng)窗口大小的變化。
為實(shí)現(xiàn)自適應(yīng)寬度。通??梢酝ㄟ^CSS來設(shè)置容器的寬度為100%,這樣它會填充父容器的寬度。
但僅僅設(shè)置CSS可能不夠,因?yàn)镋Charts實(shí)例在初始化后不會自動調(diào)整大小,除非顯式調(diào)用圖表實(shí)例的 resize 方法。
所以,解決方案的大致步驟應(yīng)該是:
- 修改模板中的div樣式,將寬度設(shè)置為100%,這樣它會根據(jù)父容器自適應(yīng)。
- 在Vue組件中添加一個監(jiān)聽窗口大小變化的事件,當(dāng)窗口resize時,觸發(fā)ECharts實(shí)例的resize方法。
- 確保在組件卸載時移除事件監(jiān)聽,避免內(nèi)存泄漏。
代碼:
<template>
<!-- 外層容器用于控制圖表寬度,高度可根據(jù)需求調(diào)整 -->
<div class="chart-container">
<div ref="chartRef" class="chart"></div>
</div>
</template>
<script setup>
import { getCurrentInstance, onMounted, onUnmounted, ref } from 'vue';
const chartRef = ref(null);
let chartInstance = null;
const { proxy } = getCurrentInstance();
// 處理窗口縮放
const handleResize = () => {
if (chartInstance) {
// 添加防抖優(yōu)化性能(可選)
chartInstance.resize();
}
};
onMounted(() => {
// 初始化圖表
chartInstance = proxy.$echarts.init(chartRef.value);
chartInstance.setOption({
title: { text: '響應(yīng)式柱狀圖' },
tooltip: {},
xAxis: { data: ['A', 'B', 'C', 'D', 'E'] },
yAxis: {},
series: [{ type: 'bar', data: [10, 20, 30, 40, 50] }]
});
// 監(jiān)聽窗口變化
window.addEventListener('resize', handleResize);
// 初始執(zhí)行一次確保尺寸正確
setTimeout(handleResize, 0);
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
chartInstance?.dispose();
});
</script>
<style scoped>
.chart-container {
width: 100%;
padding: 20px; /* 可根據(jù)需求調(diào)整 */
}
.chart {
width: 100%;
height: 200px; /* 固定高度,可改為 min-height 或使用 calc 動態(tài)計(jì)算 */
/* 可選:添加最大寬度限制 */
max-width: 1200px;
margin: 0 auto;
}
/* 移動端適配 */
@media (max-width: 768px) {
.chart {
height: 300px;
}
}
</style>效果如下:

主要修改點(diǎn)說明:
1,容器結(jié)構(gòu)優(yōu)化:
- 添加外層容器 .chart-container 控制布局
- 圖表元素使用百分比寬度 width: 100%
2,響應(yīng)式處理:
window.addEventListener('resize', handleResize);監(jiān)聽窗口縮放事件,觸發(fā)圖表 resize 方法
3,自動調(diào)整邏輯:
const handleResize = () => {
chartInstance?.resize();
};調(diào)用 ECharts 實(shí)例的 resize() 方法自適應(yīng)容器
4,CSS 增強(qiáng):
- 添加響應(yīng)式高度(通過媒體查詢)
- 限制最大寬度避免過寬
- 添加安全間距(padding/margin)
如果需要高度也自適應(yīng),可以:
// 在 handleResize 中動態(tài)計(jì)算高度
const containerWidth = chartRef.value.offsetWidth;
const aspectRatio = 9 / 16; // 16:9 比例
chartRef.value.style.height = `${containerWidth * aspectRatio}px`;
chartInstance.resize();響應(yīng)式斷點(diǎn):
/* 在樣式中添加更多斷點(diǎn) */
@media (max-width: 480px) {
.chart {
height: 250px;
}
}父容器控制:確保外層父元素有正確的布局設(shè)置
/* 在父組件中 */
.parent-container {
width: 100%;
display: flex;
justify-content: center;
}擴(kuò)展:
1,防抖處理
是否需要考慮防抖處理,避免頻繁觸發(fā)resize導(dǎo)致性能問題。但ECharts的resize方法本身有一定的優(yōu)化,可能不需要額外處理,但根據(jù)具體情況可以添加。
// 防抖版 resize(在 handleResize 頂部添加)
let resizeTimer;
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
chartInstance.resize();
}, 200);2,多圖表并列縮放問題
以兩個圖表并排并考慮縮放為例,這涉及到布局和響應(yīng)式處理兩個方面。
布局方面,我需要考慮使用CSS Flexbox或者Grid來實(shí)現(xiàn)并排。
響應(yīng)式方面,需要確保每個圖表都能在窗口大小變化時正確調(diào)整尺寸,并且可能需要在移動設(shè)備上切換為垂直排列。
接下來,我需要回憶ECharts的resize方法是否正確應(yīng)用,是否需要為每個圖表實(shí)例單獨(dú)調(diào)用resize。需要確保每個圖表容器都有正確的寬度設(shè)置,比如各占50%或者使用Flexbox的自動調(diào)整。
<template>
<!-- 使用 Flex 布局容器 -->
<div class="charts-container">
<!-- 單個圖表容器 -->
<div class="chart-wrapper">
<div ref="chartRef1" class="chart"></div>
</div>
<!-- 第二個圖表容器 -->
<div class="chart-wrapper">
<div ref="chartRef2" class="chart"></div>
</div>
</div>
</template>
<script setup>
import { getCurrentInstance, onMounted, onUnmounted, ref } from 'vue';
const chartRef1 = ref(null);
const chartRef2 = ref(null);
let chartInstance1 = null;
let chartInstance2 = null;
const { proxy } = getCurrentInstance();
// 公共配置項(xiàng)
const baseOption = {
tooltip: {},
xAxis: { data: ['A', 'B', 'C', 'D', 'E'] },
yAxis: {},
};
// 初始化圖表
const initChart = (ref, option) => {
const chart = proxy.$echarts.init(ref.value);
chart.setOption(option);
return chart;
};
// 帶防抖的 resize 處理
let resizeTimer;
const handleResize = () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
chartInstance1?.resize();
chartInstance2?.resize();
}, 200);
};
onMounted(() => {
// 初始化兩個圖表
chartInstance1 = initChart(chartRef1, {
...baseOption,
title: { text: '圖表1' },
series: [{ type: 'bar', data: [10, 20, 30, 40, 50] }]
});
chartInstance2 = initChart(chartRef2, {
...baseOption,
title: { text: '圖表2' },
series: [{ type: 'bar', data: [50, 40, 30, 20, 10] }]
});
// 監(jiān)聽窗口變化
window.addEventListener('resize', handleResize);
// 初始調(diào)整
handleResize();
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
chartInstance1?.dispose();
chartInstance2?.dispose();
});
</script>
<style scoped>
/* 主容器:Flex 布局 */
.charts-container {
display: flex;
gap: 20px; /* 圖表間距 */
width: 100%;
padding: 20px;
box-sizing: border-box;
}
/* 單個圖表容器 */
.chart-wrapper {
flex: 1; /* 平分剩余空間 */
min-width: 0; /* 解決 flex 容器溢出問題 */
}
.chart {
width: 100%;
height: 400px; /* 統(tǒng)一高度 */
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0,0,0,0.1);
}
/* 移動端響應(yīng)式 */
@media (max-width: 768px) {
.charts-container {
flex-direction: column; /* 垂直排列 */
}
.chart {
height: 300px;
}
}
</style>效果如下:

1,布局方案:
使用 display: flex 創(chuàng)建彈性容器gap: 20px 設(shè)置圖表間距flex: 1 使兩個圖表容器平分可用空間min-width: 0 修復(fù) flex 容器溢出問題
2,響應(yīng)式控制:
媒體查詢 @media (max-width: 768px) 實(shí)現(xiàn)移動端垂直布局統(tǒng)一高度設(shè)置保證視覺一致性容器寬度始終為 100% 適配父元素
3,圖表控制:
封裝 initChart 方法復(fù)用初始化邏輯使用防抖函數(shù)優(yōu)化頻繁 resize 性能同時處理兩個圖表的 resize 事件
4,樣式增強(qiáng):
添加陰影和圓角提升視覺效果設(shè)置 box-sizing: border-box 避免布局錯位背景色設(shè)置保證圖表可見性
到此這篇關(guān)于在Vue 3中使 echarts 圖表寬度自適應(yīng)變化的文章就介紹到這了,更多相關(guān)Vue echarts 圖表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue2.0中自適應(yīng)echarts圖表、全屏插件screenfull的使用
- vue3集成echarts數(shù)據(jù)刷新后圖表不刷新的解決方法
- vue之使用echarts圖表setOption多次很卡問題及解決
- Vue動態(tài)加載ECharts圖表數(shù)據(jù)的方式
- vue中實(shí)現(xiàn)當(dāng)前時間echarts圖表時間軸動態(tài)的數(shù)據(jù)(實(shí)例代碼)
- vue中Echarts圖表寬度沒占滿的問題
- vue項(xiàng)目中vue-echarts講解及常用圖表實(shí)現(xiàn)方案(推薦)
- Vue中使用Echarts可視化圖表寬度自適應(yīng)的完美解決方案
- Vue Element前端應(yīng)用開發(fā)之echarts圖表
- vue使用echarts圖表自適應(yīng)的幾種解決方案
相關(guān)文章
vue vxe-table 實(shí)現(xiàn)表格設(shè)置默認(rèn)行高同時又支持自定義行高的示例代碼
本文給大家介紹vue vxe-table如何實(shí)現(xiàn)表格設(shè)置默認(rèn)行高同時又支持自定義行高,首先將默認(rèn)行高通過css變量修改,然后再啟用自定義行高,就可以輕松實(shí)現(xiàn)這個功能了,感興趣的朋友跟隨小編一起看看吧2025-08-08
vue-router中scrollBehavior的巧妙用法
本文給大家介紹vue-router中scrollBehavior的妙用,文中給大家提到了兩種解決方案,需要的朋友可以參考下2018-07-07
解決VUE項(xiàng)目IIS部署后接口請求405錯誤問題(Method Not Allowed)
通過排查和修改IIS處理程序映射,添加ServerSideIncludeModule模塊,解決了StaticFileModule模塊報(bào)錯的問題,最終使得POST請求可以正常訪問2025-12-12
Vue3解決找不到模塊@/components/xxx.vue或其相應(yīng)的類型聲明ts文件(2307)問題
這篇文章主要介紹了Vue3解決找不到模塊@/components/xxx.vue或其相應(yīng)的類型聲明ts文件(2307)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-06-06
vue實(shí)現(xiàn)菜單權(quán)限控制的示例代碼
這篇文章主要介紹了vue實(shí)現(xiàn)菜單權(quán)限控制的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Vue3父子組件表單滾動到校驗(yàn)錯誤的位置實(shí)現(xiàn)過程
文章介紹了如何在包含父表單和多個子表單的場景中,通過滾動方法實(shí)現(xiàn)提交時的校驗(yàn)機(jī)制,確保數(shù)據(jù)完整性與用戶操作體驗(yàn)2025-07-07
vue中$emit傳遞多個參(arguments和$event)
本文主要介紹了vue中$emit傳遞多個參(arguments和$event),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02

