武漢解封,又是一年春好色!
不管有事沒事,我總喜歡把公司的項目拿出來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>
給我一瓶酒,再給我一支菸,說走就走,我有的是時間.....