前言
看到公司小伙伴在vue项目中用到echarts显示图表,都是在当前组件内直接引入echarts,然后书写一堆配置,这样会存在一些问题。
如果项目内多处需要显示图表,每次都需要引入echarts,然后初始化,再处理数据和图表容器大小变化,确实有些繁琐,其实我们都在使用vue了,完成可以封装一个基础图表组件,后面使用的时候,直接传入关于图表的配置就可以了。
基础图表组件
- 安装echarts:
npm i echarts
- 安装元素大小调整监听器:
npm i elementResizeDetectorMaker
xml
<template>
<div id="chart" ref="chart" :style="style"></div>
</template>
<script>
import * as echarts from 'echarts'
import elementResizeDetectorMaker from 'element-resize-detector'
export default {
name: 'BaseChart',
props: {
// 图表的宽度
width: {
type: String,
default: '600px'
},
// 图表的高度
height: {
type: String,
default: '400px'
},
// 图表的配置
option: {
type: Object,
required: true
}
},
data() {
return {
chart: null
}
},
computed: {
style() {
return {
width: this.width,
height: this.height
}
}
},
watch: {
option: {
deep: true,
handler() {
this.initChart()
}
}
},
mounted() {
this.initChart()
this.handleResize()
},
beforeDestroy() {
if (!this.chart) {
return
}
// 销毁图表实例
this.chart.dispose()
this.chart = null
},
methods: {
// 初始化图表
initChart() {
// 如果没有图表实例,则创建一个新的实例
if (!this.chart) {
this.chart = echarts.init(this.$refs.chart)
}
this.chart.setOption(this.option)
},
// 处理图表容器大小变化
handleResize() {
const erd = elementResizeDetectorMaker()
// 监听图表容器的大小变化
erd.listenTo(this.$refs.chart, () => {
// 改变图表尺寸
this.chart.resize()
})
}
}
}
</script>
<style lang="scss" scoped></style>
使用
使用计算属性来返回图表配置,数据变化了会重新生成配置,然后图表就会自动更新
xml
<template>
<div>
<!-- 折线图 -->
<BaseChart width="100%" height="300px" :option="lineOption" />
<div style="display: flex;height: 300px;">
<!-- 柱状图 -->
<BaseChart width="50%" height="100%" :option="barOption" />
<!-- 饼图 -->
<BaseChart width="50%" height="100%" :option="pieOption" />
</div>
</div>
</template>
<script>
import BaseChart from '@/components/BaseChart'
export default {
components: {
BaseChart
},
data() {
return {
type: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
},
computed: {
// 折线图配置
lineOption() {
const option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
type: 'line',
data: this.data,
smooth: true
}
]
}
return option
},
// 柱状图配置
barOption() {
const option = {
xAxis: {
type: 'category',
data: this.type
},
yAxis: {
type: 'value'
},
series: [
{
type: 'bar',
data: this.data
}
]
}
return option
},
// 饼图配置
pieOption() {
const option = {
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 40,
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: this.type.map((item, index) => ({
value: this.data[index],
name: item
}))
}
]
}
return option
}
},
mounted() {
this.genData()
// 开启一个定时器,数据变化后,图表也会更新
setInterval(() => {
this.data = this.genData()
}, 3000)
},
methods: {
// 生成数据
genData() {
return this.type.map(item => Math.ceil(Math.random() * 1000))
}
}
}
</script>
效果
调整窗口大小变化,图表也会自适应

结语
封装好这个基础组件后,我们在项目其他地方用到图表,直接引入这个组件就可以了,使用计算属性来返回配置,我们只关注数据即可,数据变化,图表自动变化。