tab切换显示echarts图表时,怎么解决自适应问题?

父组件用elementUI的tab放了几个tab页面(具体几个按照数据来定),在子组件中,无法通过给echarts盒子设置width:100%来使echarts图表自适应浏览器页面大小,通过监听页面变化来设置echarts的resize(),但是几个tab页面中只有一个页面能够自适应,其他的就是初始值,为什么?要怎么修改?
父组件HTML代码:

<el-tabs type="border-card" v-model="selectedTab" @tab-click="handleClick">
          <el-tab-pane v-for="(item, index) in analysisData" :key="index" :label="item.typeName" :name="index+''">
            <v-scatter :chartsData.sync="item" v-if="item.type == 10"></v-scatter>
            <v-line :chartsData.sync="item" v-else-if="item.type == 11"></v-line>
            <v-bar :chartsData.sync="item" v-else></v-bar>
</el-tab-pane>

子组件HTML代码:

<template>
  <div class="chartBox">
    <div :id="chartsData.chartId" :style="chartBox"></div>
  </div>
</template>

子组件js代码

export default {
    props: ['chartsData'],
    data(){
      return {
        chartWidth : `${document.documentElement.clientWidth}`,
        myChart: null,
        legendData:[],
        xData:[],
        seriesData: [],
        symbolSize:8
      }
    },
    computed:{
      chartBox(){
        return {width:this.chartWidth-300 + "px",height:'550px'}
      }
    },
    watch: {
      chartsData: {
        handler(newVal, oldVal){
          if(this.myChart){
            this.legendData = []
            this.seriesData = []
            this.xData = []
          }
          this.dealData()
        }
      },
    },
    mounted(){
      // 初始化时候设置echarts容器宽高
      let mychart = document.getElementById(this.chartsData.chartId);
      this.myChart = this.$echarts.init(mychart)//init创建echarts容器
      this.dealData()

      //监听页面宽度变化,并给echarts赋值
      const that = this
      window.onresize = () => {
        if(document.body.clientWidth > 1000){
          let screenWidth = document.body.clientWidth - 300
          that.chartWidth = screenWidth
          that.myChart.resize({width:screenWidth});
        }
      }
    },
    methods: {
      dealData(){
        if(this.chartsData){//判断父组件是否传值到子组件
          if(this.chartsData.result){//判断是否有Result值,画折线图
            this.chartsData.result.forEach((item, index) => {
              // this.legendData.push(item.name)
              let name = ""  //标记每个item的中文名称
              let color = ""  //标记每条折线颜色
              if(item.name == "work_day_exclude_friday"){
                name = "周一至周四"
                color = "green"
                this.legendData.push(name)
              }
              if(item.name == "friday_saturday_sunday"){
                name = "周五至周日"
                color = "black"
                this.legendData.push(name)
              }
              if(item.name == "holiday"){
                name = "节假日"
                color = "red"
                this.legendData.push(name)
              }
              if(item.result.length){
                //设置每条折线的数据
                let itemData = []
                for(var i = 0; i < item.result.length; i++){
                  itemData.push(item.result[i].value)
                  if(index == this.chartsData.result.length-1){
                    this.xData.push(item.result[i].label)
                  }
                }
                let seriesItem = {
                  name: name,
                  type: 'line',
                  symbolSize:this.symbolSize,
                  color: color,
                  data: itemData
                }
                this.seriesData.push(seriesItem)
              }
            })
          }
          if(this.chartsData.avg){//判断是否有avg值,画平均值的折线图
            this.chartsData.avg.forEach((item, index) => {
              // this.legendData.push(item.name)
              let name = ""
              let color = ""  //标记每条折线颜色(同一个类里面的本店客流量和均值客流量颜色相同)
              if(item.name == "work_day_exclude_friday"){
                name = "周一至周四均值"
                color = "green"
                this.legendData.push(name)
              }
              if(item.name == "friday_saturday_sunday"){
                name = "周四至周五均值"
                color = "black"
                this.legendData.push(name)
              }
              if(item.name == "holiday"){
                name = "节假日均值"
                color = "red"
                this.legendData.push(name)
              }
              if(item.result.length){
                //设置每条折线的数据
                let itemData = []
                for(var i = 0; i < item.result.length; i++){
                  itemData.push(item.result[i].value)
                }
                let seriesItem = {
                  name: name,
                  type: 'line',
                  symbol: 'circle',
                  symbolSize:this.symbolSize,
                  color: color,
                  data: itemData,
                }
                this.seriesData.push(seriesItem)
              }
            })
          }
          this.drawLine()
        }else{
          this.$message("暂无数据")
        }
      },
      // 画出折线图
      drawLine(){
        this.myChart.setOption({
          title: {
            text: this.chartsData.typeName,
          },
          legend: {
            align: 'left',
            left: 150,
            data: this.legendData,
          },
          tooltip : {
            trigger: 'item',
            formatter : function (params) {
              return params.seriesName + '<br/>' + params.name + ":" + params.value
            }
          },
          xAxis: {
            type: 'category',
            boundaryGap: false,
            data: this.xData
          },
          yAxis: {
            type: 'value'
          },
          series: this.seriesData
        })
      }
    }
  }

这个window.onresize只在一个子组件中有作用,其他组件中不会执行该页面的resize.
求各位大佬答疑解惑

阅读 11.1k
3 个回答

试一下在 this.$nextTick 里在再次 resize()一下

https://github.com/vuejs/vue-rx

const source = Observable.fromEvent(window, 'resize').debounceTime(100);
this.$subscribeTo(source, e => { this.$chart.resize() });

类似问题 引用我在这个问题下得回答,我觉得你的这个问题可能还是因为选项卡中切换导致div#chartsData.chartId元素是隐藏的了,所以这个echart也变形了,你应该每次切换选项卡时调用echarts.init(document.getElementById('report')); ... .... myChart.setOption(option);这个过程重新渲染。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题