el-tab 内嵌echarts图表设置宽度100%结果为100px的解决办法

原因分析

主要原因:图表设置了display:none属性上(属性含义:不为被隐藏的对象保留其物理空间,关闭元素的显示,并且所有后代元素不显示

解决方法:外部div盒子必须要在init初始化前就已经存在于dom树中(也就是已经挂载)。在监视中(watch),要配合nextTick方法使用,这样才能完全确保初始化之前,外部盒子已经存在于dom树中。

示例代码:

<template>
  <el-row :span="24">
    <el-card style="width: 100%">
      <template #header>
        <div class="card-header" style="height: 2rem; background-color: rgb(216, 219, 222)">
          <span style="padding-left: 1rem"> {
   
   { props.cardHeader }} </span>
          <div style="float: right; padding-right: 1rem">
            <DateRangePicker @date-range="getDateRange"> </DateRangePicker>
          </div>
        </div>
      </template>
      <div :id="id" :class="className" :style="{ width: width, height: height  }"></div>
    </el-card>
  </el-row>
 
</template>

<script setup lang="ts">
import { useStore } from 'vuex';
import * as echarts from 'echarts';
import { nextTick, onBeforeMount, onBeforeUnmount, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import DateRangePicker from './DateRangePicker.vue';
import axios from '../../http/axios';

const props = defineProps({
  tabName: {
    type: String,
    default: 'smoke_autotest',
    required: true,
  },
  cardHeader: {
    type: String,
    default: 'defCardHeader',
    required: true,
  },
  id: {
    type: String,
    default: 'chart',
    required: true,
  },
  className: {
    type: String,
    default: ''
  },
  width: {
    type: String,
    default: '100%',
  },
  height: {
    type: String,
    default: '10rem',
  },
  loading: {
    type: Boolean,
    default: true,
  }
});

const store = useStore();
const defaultState = reactive({
  username: store.state.userInfo.userName,
});

const tabName = ref('');
watch(props, (newV, oldV) => {
  tabName.value = newV.tabName;
  // getDeviceStatus7DaysApi();
});

const getDateRange = (cDate) => {
  // sent request here
  // defaultState.queryDate = cDate.value;
  // console.log('sent request here, ', cDate);
};

let myChart: any = null;
const resizeHandler = () => {
  myChart.resize();
};

const echartBar = () => {
  let option;

  option = {
    dataset: [
      {
        dimensions: ['xCate', 'age', 'profession', 'yValue', 'date'],
        source: [
          ['Hannah Krause', 41, 'Engineer', 314, '2011-02-12'],
          ['Zhao Qian', 20, 'Teacher', 351, '2011-03-01'],
          ['Jasmin Krause ', 52, 'Musician', 287, '2011-02-14'],
          ['Li Lei', 37, 'Teacher', 219, '2011-02-18'],
          ['Karle Neumann', 25, 'Engineer', 253, '2011-04-02'],
          ['Adrian Groß', 19, 'Teacher', '-', '2011-01-16'],
          ['Mia Neumann', 71, 'Engineer', 165, '2011-03-19'],
          ['Böhm Fuchs', 36, 'Musician', 318, '2011-02-24'],
          ['Han Meimei', 67, 'Engineer', 366, '2011-03-12'],
        ],
      },
      {
        transform: {
          type: 'sort',
          config: { dimension: 'yValue', order: 'desc' },
        },
      },
    ],
    grid: {
      height: '70%',
      top: 20,
      left: 70,
    },
    xAxis: {
      type: 'category',
      axisLabel: { interval: 0 }
    },
    yAxis: {},
    series: {
      type: 'bar',
      encode: { x: 'xCate', y: 'yValue' },
      datasetIndex: 1,
    },
  };

  option && myChart.setOption(option);
};

watch(tabName, (newV, oldV) => {
  myChart.dispose();
  myChart = null;
  window.removeEventListener('resize', resizeHandler);

  // 监听el-tab-pane 变化后,在nextTick() 重新渲染echart 图表
  nextTick(() => {
    myChart = echarts.init(document.getElementById(props.id) as HTMLDivElement, { renderer: 'svg' })
    echartBar();
    window.addEventListener('resize', resizeHandler);
  });
});

const getDeviceStatus7DaysApi = async () => {
  await axios
    .get('/controller/dashboard/devicestatusrecent', {
      params: {
        username: defaultState.username,
      },
    })
    .then((resp) => {
      if (resp.code !== 2000) {
        return;
      }
      console.log('not his, ', resp);
    });
};

onBeforeMount(() => {
  getDeviceStatus7DaysApi();
});

onMounted(() => {
  myChart = echarts.init(document.getElementById(props.id) as HTMLDivElement, { renderer: 'svg' })
  echartBar();
  window.addEventListener('resize', resizeHandler);
});

onUnmounted(() => {
  myChart.dispose();
  window.removeEventListener('resize', resizeHandler);
  myChart = null;
});
</script>

猜你喜欢

转载自blog.csdn.net/weixin_41693437/article/details/133175208
今日推荐