天天看点

Vue-图表resize事件

有时候我们会遇到这样的场景,一个组件中有几个图表,在浏览器resize的时候我们希望图表也进行resize,因此我们会在父容器组件中写:

mounted() {
  setTimeout(() => window.onresize = () => {
    this.$refs.chart1.chartWrapperDom.resize()
    this.$refs.chart2.chartWrapperDom.resize()
    // ...
  }, 200)
destroyed() { window.onresize = null }
           

这样子图表组件如果跟父容器组件不在一个页面,子组件的状态就被放到父组件进行管理,为了维护方便,我们自然希望子组件的事件和状态由自己来维护,这样在添加删除组件的时候就不需要去父组件挨个修改

优化

这里使用了lodash的节流throttle函数,也可以自己实现。 以Echarts为例,在每个图表组件中:

computed: {
  chartWrapperDom() {
    const dom = document.getElementById('consume-analy-chart-wrapper')
    return dom && Echarts.init(dom)
  },
  /**
   * 图表resize节流,这里使用了lodash,也可以自己使用setTimout实现节流
   */
  chartResize() {
    return _.throttle(() => this.chartWrapperDom && this.chartWrapperDom.resize(), 400)
  }
},
mounted() {
  window.addEventListener('resize', this.chartResize)
},
destroyed() {
  window.removeEventListener('resize', this.chartResize)
}
           

再次优化

这里因为多个 chart 实例都使用同一套初始化逻辑,可以使用 extends 来考虑复用,因此可以使用 Vue 提供的 Mixins,所以我在这里做了点优化,可以让每个同类型的 chart 组件更优雅一点: 新建一个 mixin.js 文件:

import Echarts from 'echarts'

import _ from 'lodash'

export default {
  computed: {
    $_chartMixin_chartWrapperDom() {
      const dom = document.getElementById(this.thisDomId)
      return dom && Echarts.init(dom)
    },
    /** 图表resize节流,这里使用了lodash,也可以自己使用setTimout实现节流 */
    $_chartMixin_chartResize() {
      return _.throttle(() => this.$_chartMixin_chartWrapperDom.resize(), 400)
    }
  },
  methods: {
    /* 图表初始化 */
    $_chartMixin_initChart() {
      this.$_chartMixin_chartWrapperDom.setOption({ /* options */ }
  },
  mounted() {
    this.$_chartMixin_initChart()
    window.addEventListener('resize', this.$_chartMixin_chartResize)
  },
  destroyed() {
    window.removeEventListener('resize', this.$_chartMixin_chartResize)
  }
}
           

然后在每个 chart 组件中:

<script type='text/javascript'>
import ChartMixin from './mixin'
export default {
  mixins: [ChartMixin],
  data() {
    return {
      thisDomId: 'consume-analy-chart-wrapper'
    }
  }
}
</script>
           

这样就可以在每个图表组件中混入之前在 mixin.js 中定义的 resize 事件逻辑,且自动初始化,并在 destroyed 的时候自动销毁事件~

juejin.im/post/5ae02f39518825672f198ac2