首先需要确保图表的容器存在,然后再开始渲染(v-if或者嵌套在弹框内)

借鉴PJC后的初始化

<template>
  <div :class="className" :style="{height:height,width:width}" />
</template>

<script>
import echarts from 'echarts'
import resize from '@/mixins/resize'

const animationDuration = 6000

export default {
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '300px'
    }
  },
  data() {
    return {
      chart: null
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart()
    })
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$el)

      this.chart.setOption({
        tooltip: {
          trigger: 'axis',
          axisPointer: { // 坐标轴指示器,坐标轴触发有效
            type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
          }
        },
        grid: {
          top: 10,
          left: '2%',
          right: '2%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [{
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
          axisTick: {
            alignWithLabel: true
          }
        }],
        yAxis: [{
          type: 'value',
          axisTick: {
            show: false
          }
        }],
        series: [{
          name: 'pageA',
          type: 'bar',
          stack: 'vistors',
          barWidth: '60%',
          data: [79, 52, 200, 334, 390, 330, 220],
          animationDuration
        }, {
          name: 'pageB',
          type: 'bar',
          stack: 'vistors',
          barWidth: '60%',
          data: [80, 52, 200, 334, 390, 330, 220],
          animationDuration
        }, {
          name: 'pageC',
          type: 'bar',
          stack: 'vistors',
          barWidth: '60%',
          data: [30, 52, 200, 334, 390, 330, 220],
          animationDuration
        }]
      })
    }
  }
}
</script>

且对于图表类的需求,最好写成组件以复用
tips:Echarts会在渲染的同时,将容器原本内容清空

 <div ref="chartContainer" class="chart-container"/>
import echarts from 'echarts'

 data() {
   return {
     eChart: null,
     arr: [],
   }
 },
 methods:{
 
	 initOptions() {
	     const eOptions = {
	         title: {},
	         legend: {},
	         tooltip: {
	             trigger: 'axis'
	         },
	         grid: {
	             containLabel: true
	         },
	         xAxis: {
	         	 axisLine:{},
	         	 axisLabel:{},
	             axisTick: { show: false },
	             splitLine: { show: false },
	             type: 'value',
	             data: ['day1', 'day2']
	         },
	         yAxis: {
	         	 axisLine:{},
	         	 axisLabel:{},
	             axisTick: { show: false },
	             splitLine: { show: false },
	             type: 'value'
	         },
	         series: {
	             name: '',
	             data: [10, 20],
	             type: 'line'
	         }
	     }
	     this.initChart(eOptions)
	 },

	initChart(eOptions) {
	    if (this.eChart && this.eChart.dispose) {
	        //移去上次渲染的结果,确保本次不受影响
	        this.eChart.dispose()
	    }
	
	    const eContainer = this.$refs.chartContainer
	    if (eContainer) {
	        //存在容器&&可以进一步判断数据是否为空
	        if (this.arr.length > 0) {
	            this.eChart = echarts.init(eContainer)
	            this.eChart.setOption(eOptions, true)
	        } else {
	            //没有数据的时候
	            this.initInnerHTML(eContainer)
	        }
	    } else {
	        //容器不存在
	    }
	},

	initInnerHTML(eContainer) {
	    eContainer.innerHTML = `
	      <div class="no-data-container">
	           <p class="tips">暂无数据</p>
	       </div>
	    `
	}

}
.no-data-container {
    position: relative;
    width: 100%;
    height: 100%;
}
.no-data-container .tips {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

完整代码

<template>
    <div ref="chartContainer" class="chart-container" />
</template>

<script scoped>
import echarts from "echarts";
export default {
    name: "chart",
    data() {
        return {
            eChart: null,
            arr: [{}],
            resizeTimer: null
        };
    },
    methods: {
        initOptions() {
            const eOptions = {
                title: {},
                legend: {},
                tooltip: {
                    trigger: "axis"
                },
                grid: {
                    top:'40',
                    bottom:'40',

                    left:'40',
                    right:'40',

                    containLabel: true
                },
                xAxis: {
                    axisTick: { show: false },
                    splitLine: { show: false },
                    data: ["day1", "day2"]
                },
                yAxis: {
                    axisTick: { show: false },
                    splitLine: { show: false },
                    type: "value"
                },
                series: {
                    name: "",
                    data: [10, 20],
                    type: "line"
                }
            };
            this.initChart(eOptions);
        },

        initChart(eOptions) {
            if (this.eChart && this.eChart.dispose) {
                //移去上次渲染的结果,确保本次不受影响
                this.eChart.dispose();
            }

            const eContainer = this.$refs.chartContainer;
            if (eContainer) {
                //存在容器&&可以进一步判断数据是否为空
                if (this.arr.length > 0) {
                    this.eChart = echarts.init(eContainer);
                    this.eChart.setOption(eOptions, true);
					//添加页面缩放事件
                    window.addEventListener("resize", () => {
                        if (this.resizeTimer) {
                            clearTimeout(this.resizeTimer);
                        }
                        this.resizeTimer = setTimeout(() => {
                            this.eChart.resize();
                        });
                    });
                    
                } else {
                    //没有数据的时候
                    this.initInnerHTML(eContainer);
                }
            } else {
                //容器不存在
            }
        },

        initInnerHTML(eContainer) {
            eContainer.innerHTML = `
	      <div class="no-data-container">
	           <p class="tips">暂无数据</p>
	       </div>
	    `;
        }
    },

    mounted() {
        this.initOptions();
    }
};
</script>
<style scoped>
.no-data-container {
    position: relative;
    width: 100%;
    height: 100%;
}
.no-data-container .tips {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}
</style>

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐