如何在vue中封裝一個高適用性、高擴展性的echarts

武漢解封,又是一年春好色!

不管有事沒事,我總喜歡把公司的項目拿出來da東看看,西點點,或許我是做測試的命吧。今天發現了一個問題,談不上bug,但是體驗不好。下面先上圖,看看問題所在,(敏感數據已做處理)

全屏下是這個樣子的,中規中矩,看起來還行:

如果我們把側邊欄打開,他就成了這個鬼樣子:

不用多說,想必大家已經知道問題所在了吧,下面的table用的是el-row + el-col柵格佈局,自然會適應屏幕大小尺寸的變化;而我們的echarts圖表可沒有什麼柵格佈局;仔細閱讀echarts官方文檔的同學,自然知道resize()這個方法,那麼我們要做的其實就是echarts的尺寸變化時調用resize()方法。

下面先直接上代碼,後續再解釋:

<template>
  <div ref="chartDom"></div>
</template>
<script>
import echarts from 'echarts'
// vue中監聽元素大小(尺寸)變化
import { addListener, removeListener } from 'resize-detector'
// 防抖
import debounce from 'lodash/debounce'
export default {
  props: {
    option: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
    }
  },
  watch: {
    option: {
      handler(val) {
        this.chart.setOption(this.option)
      },
      deep: true
    }
  },
  created() {
    this.resize = debounce(this.resize, 300)
  },
  mounted() {
    this.renderCharts()
    addListener(this.$refs.chartDom, this.resize)
  },
  beforeDestroy() {
    // 銷燬echart實例,防止內存溢出
    removeListener(this.$refs.chartDom, this.resize)
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    resize() {
      this.chart.resize()
    },
    // 圖表渲染
    renderCharts() {
      this.chart = echarts.init(this.$refs.chartDom)
      this.chart.setOption(this.option)
    }
  }
}
</script>

好的,仔細講解下面幾個點:

  • 安裝依賴:npm i echarts resize-detector lodash --save  ( resize-detector 監聽元素尺寸變化; lodash工具函數)
  • 爲了高擴展性,echarts中的數據/參數都是從父組件中傳遞過來的,我們封裝的組件不需要關心數據
  • addListener監聽dom元素尺寸的變化,一旦發生變化則調用echarts官方提供的resize()方法
  • 需要注意和防抖函數的結合,提高性能
  • 爲了數據實時響應,視圖立即更新,需要監聽option的變化,不過深度監聽比較耗性能,可以在父組件中對option進行賦值
  • 爲了防止內存溢出等,在鉤子函數中銷燬echarts實例

大功告成,上面的代碼,是拿來即食的那種,但是別忘了安裝相關的依賴。

下面我們就來體驗一把:

<template>
  <div>
    <h5 style="text-align:center;">echarts圖表的封裝</h5>
    <Charts v-if="chartOption" :option="chartOption" style="height:600px;"></Charts>
  </div>
</template>
<script>
import Charts from './components/Charts'
export default {
  components: {
    Charts
  },
  data() {
    return {
      chartOption: null
    }
  },
  created() {
    this.getChartsData()
    // this.changeData()
  },
  methods: {
    //這裏就是上面所說的手動賦值
    // changeData() {
    //   setInterval(() => {
    //     this.chartOption.series[0].data = [100, 150, 50, 200, 120, 700]
    //   }, 5000)
    // },
    getChartsData() {
      setTimeout(() => {
        this.chartOption = {
          title: {
            text: '瘋狂測試'
          },
          tooltip: {
            trigger: 'item'
          },
          xAxis: {
            data: ['襯衫', '羊毛衫', '雪紡衫', '褲子', '高跟鞋', '襪子']
          },
          yAxis: {},
          series: [{
            name: '銷量',
            type: 'pie',
            data: [100, 150, 50, 200, 120, 300]
          }]
        }
      }, 1000)
    }
  }
}
</script>

給我一瓶酒,再給我一支菸,說走就走,我有的是時間.....

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章