在vue3项目中使用el-tabs切换标签页时echarts图表显示不正确

一.ElementPlus中使用el-tabs

       el-tabs标签页是用来分隔内容上有关联但是属于不同类别的数据集合。Tabs组件提供了选项卡功能,默认选中第一个标签页,也可以通过value属性来指定当前选中的标签页.此外,el-tabs还提供了tab-click方法,来实现切换标签也触发的事件。下面是一个简单的示例:

<template>
  <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
    <el-tab-pane label="User" name="first">User</el-tab-pane>
    <el-tab-pane label="Config" name="second">Config</el-tab-pane>
    <el-tab-pane label="Role" name="third">Role</el-tab-pane>
    <el-tab-pane label="Task" name="fourth">Task</el-tab-pane>
  </el-tabs>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import type { TabsPaneContext } from 'element-plus'

const activeName = ref('first')

const handleClick = (tab: TabsPaneContext, event: Event) => {
  console.log(tab, event)
}
</script>

二.解决切换el-tabs标签页时echarts不能正常显示问题:

           因为在el-tabs中,一次性的把el-tabs下的所有子组件都加载出来了,这样就会使得首次没有显示的图表在显示的时候也不会正常显示;而且,在echarts挂载的dom元素有一个属性,echarts_instance,我们理解这个属性它类似于一个id,它需要每次刷新重新生成。所以在每次切换标签页的时候,就会导致echarts图表宽度高度显示不正常。

      2.1在el-tab-pane中使用lazy属性:

<el-tab-pane label="数量" key="first" name="first" :lazy="true"></el-tab-pane>

在el-tab-pane中设置lazy属性为true,就表示延迟渲染,这样,echarts就可以渲染出正常的高度和宽度了。

       2.2使用v-if判断切换当前标签页时再渲染内容:

             第一种方法我们利用的是标签页自带的lazy属性,但是我们还可以使用v-if来绑定切换标签页时再来渲染图表的事件,使用v-if方法来实现在el-tabs中只有首次显示的值为true,当点击tab切换的时候改变v-if的值,从而解决图表不能正常显示问题

<el-tabs  type="border-card"  @tab-click="handleTab" v-model="activeTab" style="margin-top: 10px;">
        <topHeader  first="创建时间" :second="second"  last="排序"/>
        <el-tab-pane label="帖子列表" name="first" >
                <div class="chart">
                    <myChart :data="chartData1" />
                </div>
            <dataList :postLabel="postLabel" :postData="postData"></dataList>
        </el-tab-pane>
        <el-tab-pane label="举报审核" name="second" :key="activeTab">
            <div class="chart">
                    <myChart :data="chartData2" v-if="key='activeTab'"/>
                </div>
            <dataList :reportLabel="reportLabel" :reportData="reportData"></dataList>
        </el-tab-pane>
    </el-tabs>
//当前激活的标签页
const activeTab=ref('first');
const second=ref('作者');
//切换标签页头部内容改变
const handleTab = (tab: any) => {
    const name = tab.props.name
    if (name === 'first') {
        second.value = '作者';
    }
    else if (name === 'second') {
        second.value = '举报者';
    }
}

这样,给v-if绑定每个标签页选项的key值,只有切换到当前标签页的时候,才会加载该图表,解决图表中不能正常显示的问题。 

       

      

### Vue使用 `el-tabs` 切换销毁 ECharts 实例的解决方案 在 VueElement UI 的开发场景下,当使用 `el-tabs` 组件并嵌入 ECharts 图表,可能会遇到因标签页切换而导致的图表渲染异常问题。例如,在切换标签页ECharts 图表可能未能正确响应其容器尺寸的变化[^1]。 #### 问题原因分析 - 当某个标签页未被激活,该页面的内容通常会被隐藏(即设置为 `display: none`),这会导致 ECharts 容器的实际宽度变为 0 或者无法正常计算。 - 如果手动处理 ECharts 实例的状态管理,则可能导致旧实例残留或者新实例初始化失败等问题[^3]。 #### 解决策略 为了确保每次切换标签页都能正确加载和更新 ECharts 图表,可以采取以下措施: 1. **监听 Tab 切换事件** 使用 `@tab-click` 或 `watch` 来捕获当前活动的标签页索引变化,并在此基础上执行必要的逻辑操作。 2. **销毁已有的 ECharts 实例** 在离开当前标签页前调用 `chart.dispose()` 方法显式销毁现有的 ECharts 实例,从而释放资源并防止冲突。 3. **重新初始化 ECharts 实例** 进入目标标签页后再次创建新的 ECharts 实例,并通过 `resize` 方法强制刷新图表布局以适配最新的 DOM 尺寸。 以下是具体实现代码示例: ```javascript <template> <el-tabs v-model="activeTab" @tab-click="handleTabClick"> <el-tab-pane label="Tab A" name="first">...</el-tab-pane> <el-tab-pane label="Tab B" name="second"> <div ref="chartContainer" style="width: 100%; height: 400px;"></div> </el-tab-pane> </el-tabs> </template> <script> export default { data() { return { activeTab: &#39;first&#39;, chartInstance: null, }; }, methods: { handleTabClick(tab) { const targetName = tab.paneName; if (targetName === &#39;second&#39;) { // 初始化第二个标签中的 ECharts 图表 this.initChart(); } else { // 销毁第一个标签对应的 ECharts 图表实例 this.destroyChart(); } }, initChart() { if (!this.chartInstance) { this.chartInstance = this.$echarts.init(this.$refs.chartContainer); const option = { title: { text: &#39;Sample Chart&#39; }, tooltip: {}, xAxis: { type: &#39;category&#39;, data: [&#39;Mon&#39;, &#39;Tue&#39;, &#39;Wed&#39;] }, yAxis: { type: &#39;value&#39; }, series: [{ data: [820, 932, 901], type: &#39;line&#39; }] }; this.chartInstance.setOption(option); window.addEventListener(&#39;resize&#39;, () => this.chartInstance.resize()); } this.chartInstance.resize(); // 调整图表大小 }, destroyChart() { if (this.chartInstance) { this.chartInstance.dispose(); // 显式销毁实例 this.chartInstance = null; window.removeEventListener(&#39;resize&#39;, () => {}); // 移除窗口调整监听器 } } }, beforeDestroy() { this.destroyChart(); // 防止组件卸载遗留未清理的实例 } }; </script> ``` 上述方法能够有效应对由于标签切换引发的各种兼容性和性能隐患[^2]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值