前言:最近一个项目刚收工,分享一个常用的封装echarts的组件。
一、直接上组件代码
<template><el-card class="echart-card" shadow="hover"><template v-slot:header><div class="card-header"><div class="card-header-title"><componentclass="icon":is="headerIcon"theme="filled"size="16":strokeWidth="3"fill="#333"/><span :class="titleStyle === 'small' ? 'title' : 'titleBig'" style="fontWeight:'bold">{{title}}</span></div><div class="card-header-right"><slot name="header-right"></slot></div></div></template><div class="echarts" ref="chartContainer" :id="`echarts${index}`" :style="style"></div></el-card>
</template>
<script setup>
import debounce from "lodash/debounce";
import {onMounted,ref,reactive,computed,watch,onBeforeUnmount,nextTick,
} from "vue";
// import { useStore } from 'vuex';
// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
import * as echarts from "echarts/core";
import { GraphicComponent } from "echarts/components";
// 引入柱状图图表,图表后缀都为 Chart
import theme from "./theme.json";
import {BarChart,CandlestickChart,FunnelChart,GaugeChart,LineChart,PieChart,RadarChart,ScatterChart,GraphChart,LinesChart,TreemapChart
} from "echarts/charts";
// 引入提示框,标题,直角坐标系组件,组件后缀都为 Component
import {TitleComponent,TooltipComponent,GridComponent,LegendComponent,ToolboxComponent,MarkPointComponent,MarkLineComponent,
} from "echarts/components";
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from "echarts/renderers";// 注册必须的组件
echarts.use([TitleComponent,TooltipComponent,GridComponent,BarChart,LineChart,PieChart,RadarChart,GaugeChart,CandlestickChart,ScatterChart,CanvasRenderer,LegendComponent,ToolboxComponent,MarkPointComponent,MarkLineComponent,FunnelChart,GraphicComponent,GraphChart,LinesChart,TreemapChart
]);const props = defineProps({// 图表下标 同个页面有多个图表时,必填index: {type: Number,default: 0,},title: {type: String,default: "标题",},headerIcon: {type: String,default: "icon-full-screen",},style: {type: Object,default: () => {return {width: "100%",height: "380px",};},},options: {type: Object,default: () => {return {};},},grid: {type: Object,default: () => {return {top: "10px",left: 0,right: "1px",bottom: 0,containLabel: true,};},},titleStyle: {type: String,default: "small",},
});let chart = null;
const chartContainer =ref(null)
let timer = ref(null);
//组件挂载完成后执行的钩子函数
onMounted(() => {window.addEventListener("resize",debounce(() => {chart.resize(); //页面大小变化后Echarts也更改大小}, 200));
});
//组件卸载之前执行的钩子函数
onBeforeUnmount(() => {clearTimeout(timer);timer = null;
});
const initChart = () => {if(chartContainer.value){if(chart){chart.dispose()}echarts.registerTheme("wonderland", theme);// chart = echarts.init(document.getElementById("echarts" + props.index), theme);chart = echarts.init(chartContainer.value, theme);// 绘制图表chart.setOption({grid: props.grid,...props.options,});}};watch(() => props.options, //监听() => {nextTick(() => {initChart();});},{deep: true,immediate: true,}
);
</script>
<style lang="scss" scoped>
.echart-card {border-radius: 10px;.card-header {display: flex;align-items: center;justify-content: space-between;&-title {display: flex;align-content: center;align-items: center;color: #606266;.icon {display: flex;padding-right: 5px;}}}.echarts {margin: 0 auto;background-color: #928f8f;}
}
</style>
二、theme.json统一风格
{"color": ["#007FC6", "#00A0F9", "#2BC7E2", "#EA7C13", "#FFB56E", "#FFE8D1"],"backgroundColor": "rgba(255,255,255,0)","textStyle": {},"title": {"textStyle": {"color": "#666666"},"subtextStyle": {"color": "#999999"}},"line": {"itemStyle": {"borderWidth": "2"},"lineStyle": {"width": "3"},"symbolSize": "8","symbol": "emptyCircle","smooth": false},"radar": {"itemStyle": {"borderWidth": "2"},"lineStyle": {"width": "3"},"symbolSize": "8","symbol": "emptyCircle","smooth": false},"bar": {"itemStyle": {"barBorderWidth": 0,"barBorderColor": "#cccccc"}},"pie": {"itemStyle": {"borderWidth": 0,"borderColor": "#cccccc"}},"scatter": {"itemStyle": {"borderWidth": 0,"borderColor": "#cccccc"}},"boxplot": {"itemStyle": {"borderWidth": 0,"borderColor": "#cccccc"}},"parallel": {"itemStyle": {"borderWidth": 0,"borderColor": "#cccccc"}},"sankey": {"itemStyle": {"borderWidth": 0,"borderColor": "#cccccc"}},"funnel": {"itemStyle": {"borderWidth": 0,"borderColor": "#cccccc"}},"gauge": {"itemStyle": {"borderWidth": 0,"borderColor": "#cccccc"}},"candlestick": {"itemStyle": {"color": "#84a2fe","color0": "transparent","borderColor": "#84a2fe","borderColor0": "#22c3aa","borderWidth": "1"}},"graph": {"itemStyle": {"borderWidth": 0,"borderColor": "#cccccc"},"lineStyle": {"width": "1","color": "#cccccc"},"symbolSize": "8","symbol": "emptyCircle","smooth": false,"color": ["#84a2fe", "#22c3aa", "#7bd9a5", "#d0648a", "#08a17e", "#f2b3c9"],"label": {"color": "#ffffff"}},"map": {"itemStyle": {"areaColor": "#eeeeee","borderColor": "#999999","borderWidth": 0.5},"label": {"color": "#28544e"},"emphasis": {"itemStyle": {"areaColor": "rgba(34,195,170,0.25)","borderColor": "#22c3aa","borderWidth": 1},"label": {"color": "#349e8e"}}},"geo": {"itemStyle": {"areaColor": "#eeeeee","borderColor": "#999999","borderWidth": 0.5},"label": {"color": "#28544e"},"emphasis": {"itemStyle": {"areaColor": "rgba(34,195,170,0.25)","borderColor": "#22c3aa","borderWidth": 1},"label": {"color": "#349e8e"}}},"categoryAxis": {"axisLine": {"show": true,"lineStyle": {"color": "#cccccc"}},"axisTick": {"show": false,"lineStyle": {"color": "#333"}},"axisLabel": {"show": true,"color": "#999999"},"splitLine": {"show": true,"lineStyle": {"color": ["#eeeeee"]}},"splitArea": {"show": false,"areaStyle": {"color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]}}},"valueAxis": {"axisLine": {"show": true,"lineStyle": {"color": "#cccccc"}},"axisTick": {"show": false,"lineStyle": {"color": "#333"}},"axisLabel": {"show": true,"color": "#999999"},"splitLine": {"show": true,"lineStyle": {"color": ["#eeeeee"]}},"splitArea": {"show": false,"areaStyle": {"color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]}}},"logAxis": {"axisLine": {"show": true,"lineStyle": {"color": "#cccccc"}},"axisTick": {"show": false,"lineStyle": {"color": "#333"}},"axisLabel": {"show": true,"color": "#999999"},"splitLine": {"show": true,"lineStyle": {"color": ["#eeeeee"]}},"splitArea": {"show": false,"areaStyle": {"color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]}}},"timeAxis": {"axisLine": {"show": true,"lineStyle": {"color": "#cccccc"}},"axisTick": {"show": false,"lineStyle": {"color": "#333"}},"axisLabel": {"show": true,"color": "#999999"},"splitLine": {"show": true,"lineStyle": {"color": ["#eeeeee"]}},"splitArea": {"show": false,"areaStyle": {"color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]}}},"toolbox": {"iconStyle": {"borderColor": "#999999"},"emphasis": {"iconStyle": {"borderColor": "#666666"}}},"legend": {"textStyle": {"color": "#999999"}},"tooltip": {"axisPointer": {"lineStyle": {"color": "#cccccc","width": 1},"crossStyle": {"color": "#cccccc","width": 1}}},"timeline": {"lineStyle": {"color": "#84a2fe","width": 1},"itemStyle": {"color": "#84a2fe","borderWidth": 1},"controlStyle": {"color": "#84a2fe","borderColor": "#84a2fe","borderWidth": 0.5},"checkpointStyle": {"color": "#84a2fe","borderColor": "#3cebd2"},"label": {"color": "#84a2fe"},"emphasis": {"itemStyle": {"color": "#84a2fe"},"controlStyle": {"color": "#84a2fe","borderColor": "#84a2fe","borderWidth": 0.5},"label": {"color": "#84a2fe"}}},"visualMap": {"color": ["#d0648a", "#22c3aa", "#adfff1"]},"dataZoom": {"backgroundColor": "rgba(255,255,255,0)","dataBackgroundColor": "rgba(222,222,222,1)","fillerColor": "rgba(114,230,212,0.25)","handleColor": "#cccccc","handleSize": "100%","textStyle": {"color": "#999999"}},"markPoint": {"label": {"color": "#ffffff"},"emphasis": {"label": {"color": "#ffffff"}}}
}
可以直接将以上两个代码复制到组件文件夹里面
三、使用该组件
<EchartsComtitle="协议流量趋势图":index="11":titleStyle="'big'"headerIcon="icon-chart-line":style="{ height: '250px' }":options="{tooltip: trendSeries.tooltip,series: trendSeries.series,xAxis: trendSeries.xAxis,yAxis: trendSeries.yAxis,grid: trendSeries.grid,}"></EchartsCom>
可以很清楚的看到,其实主要就是传echarts的配置。
配置代码(就以折线图举例):
const trendSeries = ref({grid: { top: '15%', bottom: '5%', left: '10%', right: '18%', containLabel: true },tooltip: {trigger: 'axis',axisPointer: {type: 'line',},},series: {type: 'line',data: [120, 132, 101, 134, 90, 230, 210],symbol: 'circle',lineStyle: {normal: {color: '#008FFF',},},symbolSize: 10,itemStyle: {normal: {color: '#fff',borderColor: '#008FFF',},borderRadius: [30, 30, 0, 0],shadowColor: 'rgb(255,255,255)',shadowBlur: 4,},smooth: false,},xAxis: {name: '时间',type: 'category',data: ['2024-04-18','2024-04-19','2024-04-20','2024-04-21','2024-04-22','2024-04-23','2024-04-24',],splitLine: {show: false,},axisLabel: {color: '#002745',},},yAxis: {name: '单位(次)',type: 'value',minInterval: 1,splitLine: {show: true,lineStyle: {width: 2,type: 'dashed',},},axisLine: {show: false,},axisLabel: {show: true,formatter(v) {v = v.toString();if (v >= 100000000000) {return v.substring(0, 5) / 10 + '亿';} else if (v >= 10000000000) {return v.substring(0, 4) / 10 + '亿';} else if (v >= 1000000000) {return v.substring(0, 3) / 10 + '亿';} else if (v >= 100000000) {return v.substring(0, 2) / 10 + '亿';} else if (v >= 10000000) {return v.substring(0, 4) + '万';} else if (v >= 1000000) {return v.substring(0, 3) + '万';} else if (v >= 100000) {return v.substring(0, 2) + '万';} else if (v >= 10000) {return v.substring(0, 2) / 10 + '万';} else if (v >= 1000) {return v;} else {return v;}},},},});
效果展示:
如果想用饼图、柱状图之类的就可以直接传相应的配置即可,这样可以灵活控制每个图的不用样式。
之前我封装过几个组件都是把echarts的配置写进组件里面,但是后面发现如果一个页面需要七八个echarts图表,并且样式都是不一样的,那么就比较适用该文介绍的封装方法。