武汉解封,又是一年春好色!
不管有事没事,我总喜欢把公司的项目拿出来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>
给我一瓶酒,再给我一支烟,说走就走,我有的是时间.....