笔记 vue2 echarts 简单封装 配合 自定义指令 v-resize

102 阅读1分钟

Chart 组件

<template>
  <div class="chart_box" :style="{ width, height }">
    <div
      class="chart"
      ref="chart"
      v-resize="resize"
      :style="{ zIndex: isNotEmpty ? 1 : -1 }"
    ></div>
    <div class="chart-empty" :style="{ zIndex: isNotEmpty ? -1 : 1 }">
      <a-empty></a-empty>
    </div>
  </div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  props: {
    option: {
      type: Object,
      required: true,
    },
    width: {
      type: String,
      default: '100%',
    },
    height: {
      type: String,
      default: '100%',
    },
  },
  data() {
    return {
      chartInstance: null,
    };
  },
  computed: {
    isNotEmpty() {
      return this.option?.series && this.option?.series?.length > 0;
    },
  },
  beforeDestroy() {
    if (this.chartInstance) {
      this.chartInstance.dispose();
    }
  },
  directives: {},
  watch: {
    option: {
      handler(newVal) {
        this.chartInstance.setOption(newVal);
      },
      deep: true,
    },
  },
  mounted() {
    this.initChart();
  },
  methods: {
    initChart() {
      this.chartInstance = echarts.init(this.$refs.chart);
      this.chartInstance.setOption(this.option);
    },
    resize() {
      this.chartInstance?.resize();
    },
    setOption(option) {
      this.chartInstance?.setOption(option);
    },
  },
  beforeDestroy() {
    if (this.chartInstance) {
      this.chartInstance.dispose();
    }
  },
};
</script>

<style scoped lang="less">
.chart_box {
  position: relative;
}
.chart-empty {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}
.chart {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
</style>

自定义指令 v-resize

const resize = {
  bind(el, binding, vnode) {
    el.__resize__ = function (event) {
      binding.value(event, el);
    };
    window.addEventListener('resize', el.__resize__);
  },
  unbind(el) {
    window.removeEventListener('resize', el.__resize__);
    delete el.__resize__;
  }
};
export default resize;

demo

<template>
  <Chart :option="option" />
</template>

<script>
import Chart from '@/project/components/Chart.vue';
export default {
  components: {
    Chart,
  },
  data() {
    return {
      option: {
        grid: {
          left: '30',
          right: '0%',
          bottom: '46',
          top: '20',
          containLabel: true,
        },
        xAxis: {
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'Fri', 'Sat', 'Sun'],
        },
        yAxis: {
          type: 'value',
        },
        series: [
          {
            type: 'bar',
            data: [150, 230, 224, 218, 135, 147, 260, 135, 147, 260],
            barWidth: '40%',
            color: '#3AA0FF',
          },
        ],
      },
    };
  },
  watch: {
    
  }
};
</script>

<style scoped>
/* 可以添加一些样式来美化页面 */
</style>