【ECharts✨】解决Vue 中 v-show 导致组件 ECharts 样式异常问题

解决Vue 中 v-show 导致组件 ECharts 样式异常问题

问题概述

在使用 Vue 的 v-show 指令实现 <PageOne/><PageTwo/><PageThree/> 三个视图的定时切换时,<PageTwo/> 显示时出现了异常,具体表现为 ECharts 图表渲染图表尺寸异常问题,严重影响了页面的正常展示和用户体验。

错误原因

v-show 的隐藏机制通过设置 display: none 隐藏元素,虽然元素仍然保留在 DOM 中,但它不参与页面的布局计算,因此宽高被计算为 0 。当 ECharts 初始化时,它依赖容器的实际尺寸 来渲染图表。如果此时容器处于隐藏状态,ECharts 会以 0 尺寸进行渲染,之后切换为可见时,图表无法自动修正其尺寸,导致图表渲染异常 。

解决方法:

🌟延迟初始化并重绘图表

  1. 父组件传递显示状态

    在父组件中使用 currentPage 判断,并通过 isVisible 属性告知 <PageTwo/> 当前是否可见:

    html 复制代码
    <!-- 父组件模板 -->
    <PageTwo
      v-show="currentPage === 2"
      :is-visible="currentPage === 2"
    />
       ```
  2. 在 PageTwo 中监听并重绘

    PageTwo 接收 isVisible,通过 watch 监听其变化,在可见时延迟执行图表初始化和尺寸更新:

    javascript 复制代码
    <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'))

完整代码

父组件

html 复制代码
<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 组件

html 复制代码
<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>

总结

  1. 使用 v-show 切换 <PageTwo/> 时,is-visible 属性用于控制页面是否可见。
  2. <PageTwo/> 中监听is-visible,当页面显示时,使用 nextTick 延迟执行,确保 DOM 更新后初始化图表并调整尺寸
  3. 使用 initChart 初始化 ECharts 图表handleWindowResize 用于触发窗口尺寸变化,确保图表正确渲染。

这段代码确保在使用 v-show 显示<PageTwo/> 时,ECharts 图表能够根据正确的尺寸重新初始化,解决因 v-show 隐藏导致的初始化问题。

相关推荐
JustHappy8 小时前
古法编程秘籍(七):互联网到底是什么?把两台电脑怎么说话搞懂就够了
前端·后端·网络协议
老毛肚8 小时前
jeecg-boot-base-core 02 day
javascript·python
snow@li8 小时前
SEO-文章标题:写文章时候,分类+主标题+大纲+解释 作为标题 / 不点进去也知道全文覆盖什么 / 标题即架构
前端
kyriewen9 小时前
Git Commit 前自动修复代码风格?配置 Husky + lint-staged,从此 CR 只聊逻辑
前端·git·面试
岁月宁静9 小时前
RAG 文档摄入全链路,从原理到生产落地
vue.js·人工智能·python
小和尚同志10 小时前
AI 自动化测试探索(一):Playwright MCP
前端·人工智能·aigc
老马识途2.010 小时前
在AI的帮助下理解spring的启动过程
java·前端·spring
徐小夕10 小时前
Loop Engineering 深度解析与实战指南(全网最全)
前端·算法·github
运筹vivo@11 小时前
Python ContextVar 底层机制与内存模型拆解
前端·数据库·python
#麻辣小龙虾#12 小时前
基于vue3.0开发一款【固废与废气运维管理系统】(支持源码)
前端·vue.js·vue3