echarts 基础封装 监听页面宽度变化

在这里插入图片描述

ChartPanel – index.vue
<template>
  <div ref="chartPanel" class="chart-panel" :class="className" :style="{ height: height, width: width }" />
</template>

<script>
// echarts v4 import
// import echarts from 'echarts'
// echarts v5 import
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'

export default {
  name: 'ChartPanel',
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '100%'
    },
    mini: {
      type: Boolean,
      default: false
    },
    autoResize: {
      type: Boolean,
      default: true
    },
    option: {
      type: Object,
      required: true
    },
    initName: {
      type: String,
      default() { return '' }
    },
    initMap: {
      type: Object,
      default: null
    }
  },
  data() {
    return {
      chart: null,
      timer: null
    }
  },
  watch: {
    option: {
      deep: true,
      handler(val) {
        if (this.initName && this.initMap) {
          // echarts更新到5.x之后就不能重新设置option了 必须重新init图形
          this.initChart()
        } else {
          if (this.chart) {
            this.chart.clear()
            const that = this
            that.timer = setTimeout(() => {
              that.chart.setOption(val, true)
            }, 500)
          }
        }
      }
    },
    initName: {
      deep: true,
      handler(val) {
        this.initChart()
        this.resize()
      }
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart()
    })
    if (this.autoResize) {
      this.__resizeHandler = debounce(() => {
        if (this.chart) {
          this.chart.resize()
        }
      }, 100)
      window.addEventListener('resize', this.__resizeHandler)
    }
    // 监听侧边栏的变化
    this.sidebarElm = document.getElementsByClassName('sidebar-container')[0]
    this.sidebarElm && this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler)
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    if (this.autoResize) {
      window.removeEventListener('resize', this.__resizeHandler)
    }

    this.sidebarElm && this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler)
    this.chart.dispose()
    this.chart = null
    clearTimeout(this.timer)
  },
  methods: {
    sidebarResizeHandler(e) {
      if (e.propertyName === 'width') {
        this.__resizeHandler()
      }
    },
    initChart() {
      this.chart = echarts.init(this.$el)
      // this.chart = echarts.init(this.$el, 'macarons')
      if (this.initName && this.initMap) {
        echarts.registerMap(this.initName, this.initMap)
      }
      if (this.option != null) {
        this.chart.clear()
        const that = this
        this.timer = setTimeout(() => {
          that.chart.setOption(that.option, true)
        }, 500)
      }
      this.$emit('initChart', this.chart)
    },
    resize() {
      if (this.chart != null) {
        this.chart.resize()
      }
    }
  }
}
</script>
debounce方法:
/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result;

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp;

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      }
    }
  };

  return function(...args) {
    context = this;
    timestamp = +new Date();
    const callNow = immediate && !timeout;
    // 如果延时不存在,重新设定延时
    if (!timeout) timeout = setTimeout(later, wait);
    if (callNow) {
      result = func.apply(context, args);
      context = args = null;
    }

    return result;
  };
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值