解決Vue 中 v-show 導致組件 ECharts 樣式異常問題
問題概述
在使用 Vue 的 v-show
指令實現 <PageOne/>
、<PageTwo/>
、<PageThree/>
三個視圖的定時切換時,<PageTwo/>
顯示時出現了異常,具體表現為 ECharts 圖表渲染圖表尺寸異常問題,嚴重影響了頁面的正常展示和用戶體驗。
錯誤原因
v-show 的隱藏機制通過設置 display: none
隱藏元素,雖然元素仍然保留在 DOM 中,但它不參與頁面的布局計算,因此寬高被計算為 0。當 ECharts 初始化時,它依賴容器的實際尺寸來渲染圖表。如果此時容器處于隱藏狀態,ECharts 會以 0 尺寸進行渲染,之后切換為可見時,圖表無法自動修正其尺寸,導致圖表渲染異常 。
解決方法:
🌟延遲初始化并重繪圖表
-
父組件傳遞顯示狀態
在父組件中使用
currentPage
判斷,并通過isVisible
屬性告知<PageTwo/>
當前是否可見:<!-- 父組件模板 --> <PageTwov-show="currentPage === 2":is-visible="currentPage === 2" />```
-
在 PageTwo 中監聽并重繪
PageTwo 接收 isVisible,通過 watch 監聽其變化,在可見時延遲執行圖表初始化和尺寸更新:
<script setup> import { ref, watch, nextTick } from 'vue'; import { initChart, handleWindowResize } from '@/utils/chartHelper';const props = defineProps({ isVisible: Boolean }); const gridItems = ref([]);watch(() => props.isVisible,(visible) => {if (visible) {// 等待 DOM 完全渲染nextTick(() => {// 重新初始化每個圖表gridItems.value.forEach(item => initChart(item.id));// 觸發全局 resize,通知 ECharts 更新尺寸handleWindowResize();});}},{ immediate: true } ); </script>
說明:確保
initChart
方法內部調用了echarts.init(dom)
并配置了必要的選項,handleWindowResize
則使用window.dispatchEvent(new Event('resize'))
。
完整代碼
父組件
<template><div><button @click="currentPage = 1">Page One</button><button @click="currentPage = 2">Page Two</button><button @click="currentPage = 3">Page Three</button><!-- 使用 v-show 切換頁面 --><PageTwo v-show="currentPage === 2" :is-visible="currentPage === 2" /></div>
</template><script setup>
import { ref } from 'vue';
import PageTwo from './PageTwo.vue'; // 假設 PageTwo.vue 為子組件const currentPage = ref(1);
</script>
PageTwo 組件
<template><div class="page-two"><div class="chart-container" v-for="item in gridItems" :key="item.id" :id="item.id"><!-- 圖表容器 --></div></div>
</template><script setup>
import { ref, watch, nextTick } from 'vue';
import { initChart, handleWindowResize } from '@/utils/chartHelper'; // 假設這些方法已定義const props = defineProps({isVisible: {type: Boolean,default: false}
});const gridItems = ref([{ id: 'chart1' },{ id: 'chart2' }
]);// 監聽 isVisible,確保在頁面顯示時重新初始化圖表
watch(() => props.isVisible, (isVisible) => {if (isVisible) {nextTick(() => {// 重新初始化每個圖表gridItems.value.forEach(item => initChart(item.id));// 觸發窗口resize,通知 ECharts 更新尺寸handleWindowResize();});}
}, { immediate: true });
</script><style scoped>
/* 你的樣式 */
.chart-container {width: 100%;height: 400px;
}
</style>
總結
- 使用 v-show 切換
<PageTwo/>
時,is-visible 屬性用于控制頁面是否可見。- 在
<PageTwo/>
中監聽is-visible,當頁面顯示時,使用nextTick
延遲執行,確保 DOM 更新后初始化圖表并調整尺寸。- 使用 initChart 初始化 ECharts 圖表,
handleWindowResize
用于觸發窗口尺寸變化,確保圖表正確渲染。
這段代碼確保在使用 v-show 顯示<PageTwo/>
時,ECharts 圖表能夠根據正確的尺寸重新初始化,解決因 v-show 隱藏導致的初始化問題。