vue-Tabs 标签页中使用ECharts

879 阅读1分钟

「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」。

vue中如何使用ECharts画图并实现自适应 中我们阐述并实现了如何在 div 中自适应画图。

但是当把图表嵌套在 Tabs 标签页中时, vue中如何使用ECharts画图并实现自适应 中的方法一、方法二、方法三全部失效了。

1. Tabs 标签页中嵌套画图

具体代码如下:

<template>
  <div class="app-container">
    <el-tabs v-model="active" class="chartCon" type="card">
      <el-tab-pane label="1111111111" name="first">
        <div class="normalStyle">
          <div id="main1" style="width:100%;height:100%" />
        </div>
        <div class="normalStyle">
          <div id="main2" style="width:100%;height:100%" />
        </div>
      </el-tab-pane>

      <el-tab-pane label="2222222222" name="second">
        <div class="normalStyle">
          <div id="main3" style="width:100%;height:100%" />
        </div>
        <div class="normalStyle">
          <div id="main4" style="width:100%;height:100%" />
        </div>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
import { EleResize } from '@/utils/esresize'// 图表自适应
export default {
  data() {
    return {
      active: 'first'
    }
  },

  mounted() {
    // 画图
    this.initChart(document.getElementById('main1'), '111111111')
    this.initChart(document.getElementById('main2'), '222222222')
    this.initChart(document.getElementById('main3'), '333333333')
    this.initChart(document.getElementById('main4'), '444444444')
  },

  methods: {
    initChart(domName, title) {
      var myChart = this.$echarts.init(domName)

      // 自适应
      var listener = function() {
        myChart.resize()
      }
      EleResize.on(domName, listener)

      var option = {
        title: {
          text: title
        },
        legend: {
          data: ['销量']
        },
        xAxis: {
          data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {},
        series: [
          {
            name: '销量',
            type: 'bar',
            data: [5, 20, 36, 10, 10, 20]
          }
        ]
      }

      // 绘制图表
      option && myChart.setOption(option)
    }
  }
}
</script>

<style lang="scss">
.chartCon{
  width: calc(100% - 40px);
  background-color: #fff;
  position: absolute;
  left: 20px;
  right: 20px;
  bottom: 20px;
  top: 20px;
  .el-tabs__content{
    width: 100%;
    height: calc(100% - 56px);
    background-color: #ffffda;
    .normalStyle{
      width:50%;
      height:100%;
      float:left;
      border: 1px solid #eee;
    }
  }
}
</style>

2.存在的问题

1)页面初次渲染时,图表容器的高度没有按100%进行渲染,如图所示:

2)即使手动点击浏览器刷新按钮,图表渲染也是不正常的,效果跟问题1一样;

3)即使使用了自适应方法 esresize,图表的宽度可以自适应,但高度仍然无法自适应;

4)当浏览器窗口大小发生变化后,Tab1、Tab2来回切换时,Tab 中的图表渲染发生错乱现象,如图:

总之就是怎么渲染都不对。

3.解决办法

针对 Tabs 标签页中嵌套画图存在的问题,使用 vue中如何使用ECharts画图并实现自适应 中的补充可解决,具体代码如下:

<template>
  <div class="app-container">
    <el-tabs v-model="active" class="chartCon" type="card">
      <el-tab-pane label="1111111111" name="first">
        <div class="normalStyle">
          <div id="main1" :style="'width:' + normalWidth/2 + 'px;height:' + normalHeight + 'px'" />
        </div>
        <div class="normalStyle">
          <div id="main2" :style="'width:' + normalWidth/2 + 'px;height:' + normalHeight + 'px'" />
        </div>
      </el-tab-pane>

      <el-tab-pane label="2222222222" name="second">
        <div class="normalStyle">
          <div id="main3" :style="'width:' + normalWidth/2 + 'px;height:' + normalHeight + 'px'" />
        </div>
        <div class="normalStyle">
          <div id="main4" :style="'width:' + normalWidth/2 + 'px;height:' + normalHeight + 'px'" />
        </div>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
import { EleResize } from '@/utils/esresize'// 图表自适应
export default {
  data() {
    return {
      active: 'first',
      screenHeight: window.innerHeight,
      screenWidth: window.innerWidth,
      normalHeight: window.innerHeight - 146,
      normalWidth: window.innerWidth
    }
  },

  watch: {
    // 监听screenHeight和screenWidth从而实现自适应宽高
    screenHeight(val) {
      this.screenHeight = val
      this.normalHeight = this.screenHeight - 146
    },
    screenWidth(val) {
      this.screenWidth = val
      this.normalWidth = this.screenWidth
    }
  },

  mounted() {
    // 画图
    this.initChart(document.getElementById('main1'), '111111111')
    this.initChart(document.getElementById('main2'), '222222222')
    this.initChart(document.getElementById('main3'), '333333333')
    this.initChart(document.getElementById('main4'), '444444444')

    // 浏览器窗口变化触发,获取当前浏览器窗口大小
    window.onresize = () => {
      return (() => {
        window.screenHeight = window.innerHeight
        window.screenWidth = window.innerWidth
        this.screenHeight = window.screenHeight
        this.screenWidth = window.screenWidth
      })()
    }
  },

  methods: {
    initChart(domName, title) {
      var myChart = this.$echarts.init(domName)

      // 自适应
      var listener = function() {
        myChart.resize()
      }
      EleResize.on(domName, listener)

      var option = {
        title: {
          text: title
        },
        legend: {
          data: ['销量']
        },
        xAxis: {
          data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {},
        series: [
          {
            name: '销量',
            type: 'bar',
            data: [5, 20, 36, 10, 10, 20]
          }
        ]
      }

      // 绘制图表
      option && myChart.setOption(option)
    }
  }
}
</script>

<style lang="scss">
.chartCon{
  width: calc(100% - 40px);
  background-color: #fff;
  position: absolute;
  left: 20px;
  right: 20px;
  bottom: 20px;
  top: 20px;
  .el-tabs__content{
    width: 100%;
    height: calc(100% - 56px);
    background-color: #ffffda;
    .normalStyle{
      width:50%;
      height:100%;
      float:left;
      border: 1px solid #eee;
    }
  }
}
</style>

页面渲染效果如图:

有时候当从Tab1 切换到 Tab2,再从 Tab2 切换回 Tab1时,会出现图表渲染不出来的情况,虽然我这里没出现,但是为了保险起见,需要修改 initChart 方法中的代码如下:

initChart(domName, title) {
      var myChart

      if (myChart !== null && myChart !== '' && myChart !== undefined) {
        // 清除实例中的组件和图表
        myChart.clear()

        // 销毁实例,销毁后实例无法再被使用(适用于有tab标签时)
        myChart.dispose()
      }

      myChart = this.$echarts.init(domName)

      // 自适应
      var listener = function() {
        myChart.resize()
      }
      EleResize.on(domName, listener)

      var option = {
        title: {
          text: title
        },
        legend: {
          data: ['销量']
        },
        xAxis: {
          data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {},
        series: [
          {
            name: '销量',
            type: 'bar',
            data: [5, 20, 36, 10, 10, 20]
          }
        ]
      }

      // 绘制图表
      option && myChart.setOption(option)
    }