【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 隐藏导致的初始化问题。

相关推荐
迪丽热爱4 分钟前
解决【npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。】问题
前端·npm·node.js
数字冰雹12 分钟前
图观 流渲染场景服务器
服务器·前端·数据库·数据可视化
533_15 分钟前
[element-plus] el-select 下拉选择图片
vue.js
李明卫杭州18 分钟前
详细讲解js中的ResizeObserver
前端·javascript
千叶寻-36 分钟前
package.json详解
前端·vue.js·react.js·webpack·前端框架·node.js·json
小*-^-*九40 分钟前
Electron vue项目 打包 exe文件2
javascript·vue.js·electron
zhengjianyang&1231 小时前
美团滑块-[behavior] 加密分析
javascript·经验分享·爬虫·算法·node.js
zz-zjx1 小时前
Web接入层的“铁三角”---防盗链、反向代理,负载均衡(nginx)
前端·nginx·负载均衡
C+ 安口木1 小时前
CSS通用优惠券样式
前端·css
小趴菜82271 小时前
安卓人机验证View
android·java·前端