为什么要有封装组件这一步骤
在常见的业务处理过程中,我们常常可以发现很多类似的操作:实现多个echarts图表、多个表格数据等等,而这些处理,其实大体格式都是一样的,只是数据不同,以及每个组件元素的属性不一样,比如有的是柱状图,有的是饼状图等。于是,我们可以通过封装组件的方式来解决这个问题。
如何封装一个组件
封装echarts组件
我们现对如上所示图表进行组件的封装。
link:Apache ECharts
1. 首先确定要封装的组件类型
有哪几种类型:柱状图、现状图、饼状图。因此有两类:需要设置x、y坐标轴的图表和不需要设置x、y坐标轴的图表。即需要建立两个option配置项axisOption和normalOption。
2.配置axisOption通用属性:
axisOption: {
legend: {
// 图例文字颜色
textStyle: {
color: "#333",
},
},
grid: {
left: "20%",
},
// 提示框
tooltip: {
trigger: "axis",
},
xAxis: {
type: "category", // 类目轴
data: [],
axisLine: {
lineStyle: { // x轴坐标轴线线的颜色
color: "#17b3a3",
},
},
axisLabel: {
interval: 0, // 坐标轴刻度标签的显示间隔
color: "#333",
},
},
yAxis: [
{
type: "value",
axisLine: {
lineStyle: {
color: "#17b3a3",
},
},
},
],
color: ["#2ec7c9", "#b6a2de"], // 调色盘
series: [], // 数据
},
3.配置normalOption通用属性
// 这里只用到了最简易的饼状图,因此配置属性只有几项
normalOption: {
tooltip: {
trigger: "item",
},
color: ["#0f78f4", "#dd536b", "#9462e5", "#a6a6a6", "#e1bb22", "#39c362", "#3ed1cf"],
series: [],
},
4.组件间传值
使用该组件时,需要确认使用哪种类型,因此需要传递一个值用来判断,同时还要将数据传递
props: {
isAxisChart: { // 是否为柱状图、折线图,默认是
type: Boolean,
default: true,
},
chartData: { // 图表数据
type: Object,
default() {
return {
xData: [],
series: [],
};
},
},
},
接受传递过来的值之后,进一步处理,根据isAxisChart确定使用哪种配置,这里需要进行逻辑判断,使用计算属性较为适宜。
computed: {
options() {
return this.isAxisChart ? this.axisOption : this.normalOption;
},
},
5.初始化
经过以上配置以后,echarts的基本属性已封装完毕,下面就是进行初始化和调用。
我们知道,echarts的初始化,需要获取标签元素,然后设置配置项。
initChart() {
this.initChartData(); // 这里将接受的值并入配置项中
if (this.echart) { // 当数据更新时,需要重新渲染,但是之前已经获取过标签元素,这里可以不用重复获取
this.echart.setOption(this.options);
} else {
this.echart = echarts.init(this.$refs.echarts);
this.echart.setOption(this.options);
}
},
将接受的值并入配置项中
initChartData() {
if (this.isAxisChart) { // 根据图表的类型,进行并入
this.axisOption.xAxis.data = this.chartData.xData;
this.axisOption.series = this.chartData.series;
} else {
this.normalOption.series = this.chartData.series;
}
<img src="}," alt="" width="70%" />
6.数据动态渲染
要实现数据的动态渲染,那就需要知道数据什么变化了,然后将变化后的数据重新渲染,这里适合用监听器实现
watch: {
chartData: { // 接收的数据
handler: function () {
this.initChart(); // 重新渲染
},
deep: true, // 被侦听的对象的 property 改变时被调用,不论其被嵌套多深
},
},
完整封装代码
<template>
<div ref="echarts"></div>
</template>
<script>
import * as echarts from "echarts";
export default {
props: {
isAxisChart: {
type: Boolean,
default: true,
},
chartData: {
type: Object,
default() {
return {
xData: [],
series: [],
};
},
},
},
data() {
return {
axisOption: {
legend: {
// 图例文字颜色
textStyle: {
color: "#333",
},
},
grid: {
left: "20%",
},
// 提示框
tooltip: {
trigger: "axis",
},
xAxis: {
type: "category", // 类目轴
data: [],
axisLine: {
lineStyle: {
color: "#17b3a3",
},
},
axisLabel: {
interval: 0,
color: "#333",
},
},
yAxis: [
{
type: "value",
axisLine: {
lineStyle: {
color: "#17b3a3",
},
},
},
],
color: ["#2ec7c9", "#b6a2de"],
series: [],
},
normalOption: {
tooltip: {
trigger: "item",
},
color: ["#0f78f4", "#dd536b", "#9462e5", "#a6a6a6", "#e1bb22", "#39c362", "#3ed1cf"],
series: [],
},
echart: "",
};
},
methods: {
initChart() {
this.initChartData();
if (this.echart) {
this.echart.setOption(this.options);
} else {
this.echart = echarts.init(this.$refs.echarts);
this.echart.setOption(this.options);
}
},
initChartData() {
if (this.isAxisChart) {
this.axisOption.xAxis.data = this.chartData.xData;
this.axisOption.series = this.chartData.series;
} else {
this.normalOption.series = this.chartData.series;
}
},
},
watch: {
chartData: {
handler: function () {
this.initChart();
},
deep: true,
},
},
computed: {
options() {
return this.isAxisChart ? this.axisOption : this.normalOption;
},
},
};
</script>
<style></style>
调用示例
在父组件中,调用封装好的Echart组件,将图表类型和数据传递给Echart组件,因为是饼状图,只需要传递一个series配置即可
<Echart style="height: 235px" :isAxisChart="false" :chartData="echarts.video" />
echarts: {
video: {
series: [],
},
}