欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > vue-cli + echarts 组件封装 (Vue2版)

vue-cli + echarts 组件封装 (Vue2版)

2025/3/12 5:14:05 来源:https://blog.csdn.net/qq_44408913/article/details/146101384  浏览:    关键词:vue-cli + echarts 组件封装 (Vue2版)

在Vue2中使用ECharts还是比较麻烦的,今天做了几个组件让我们能更加简单的调用Echars来显示图表。

效果展示

在这里插入图片描述
在这里插入图片描述

echarts 导入

这里我们使用 package.json 方式导入Echars。配置好后使用命令 npm install或者其他方式都可以

{// ... "scripts": {// ... "setYarn": "yarn config set registry https://registry.npmmirror.com/", // 设置yarn镜像地址"yarnInstall": "yarn install", // yarn}// ... "dependencies": {// ... "echarts": "^5.4.3", // 博主用的是这个版本可根据自己需求修改}// ... 
}

父组件引用

<template><div><!-- 操作按钮区域 --><div><a-button @click="loadData" type="primary" icon="sync">刷新</a-button></div><EBarChart title='MSA偏倚直方图' :data="barData" x-label='测量值' y-label='频数' width="90%" height="500px" /><ELineChart title='' :data="barData" x-label='测量值' y-label='频数' width="90%" height="500px" /><EPieChart title='' :data=" [{ value: 1048, name: '测量值1' },{ value: 735, name: '测量值2' },{ value: 580, name: '测量值3' },]" width="90%" height="500px" /></div>
</template><script>
import { getAction } from '@/api/manage';
import EBarChart from '@comp/EChart/EBarChart.vue';
import ELineChart from '@comp/EChart/ELineChart.vue'
import EPieChart from '@comp/EChart/EPieChart.vue'export default {name: '',components: { ELineChart, EBarChart, EPieChart },data() {return {dataSource: [],chartOptions: {},barData: {x:[],y:[],},url: {list: '/msa/msaBias/listAllMsaGroupDataByMainId',},};},methods: {clearList() {this.dataSource = [];},loadData() {this.chartOptions = {};this.barData = {x: [],y: []};// 这里是请求服务器数据的方式 如果不需要自行修改getAction(this.url.list, { pid: this.mainId }).then(res => {if (res.success) {this.dataSource = res.result.records || res.result;const xData = this.dataSource.map(item => String(item.minValue)); // 确保是字符串const yData = this.dataSource.map(item => Number(item.sampleCount)); // 确保是数值this.barData = {x: xData,y: yData};} else {this.$message.error(res.message);}});},},
};
</script><style scoped></style>

柱状图组件

<template><div ref="chartContainer" :style="{ width: width, height: height }"></div>
</template><script>
import * as echarts from 'echarts';export default {name: 'EBarChart',props: {title: { type: String, default: "柱状图" },xLabel: { type: String, default: "" },yLabel: { type: String, default: "" },options: { type: Object, default: () => ({}) },// 自定义optionsdata: { type: Object, default: () => ({}) }, // 调用方式{x:[],y:[]}width: { type: String, default: '100%' },height: { type: String, default: '400px' },},data() {let xLabel = this.xLabellet yLabel = this.yLabelreturn {chartInstance: null,defaultOptions: {// 标题配置title: {text: this.title, // 标题文本left: 'center', // 标题位置(居中)top: '0px', // 标题距离图表顶部 20pxtextStyle: {fontSize: 25, // 标题字体大小fontWeight: 'bold', // 标题字体加粗color: '#333', // 标题字体颜色},},// 提示框配置tooltip: {trigger: 'axis', // 触发方式(坐标轴触发)backgroundColor: 'rgba(50, 50, 50, 0.7)', // 提示框背景颜色borderColor: '#333', // 提示框边框颜色borderWidth: 1, // 提示框边框宽度padding: 10, // 提示框内边距textStyle: {fontSize: 18, // 提示框字体大小color: '#fff', // 提示框字体颜色},formatter: function (params) {// 自定义提示框内容return `${yLabel}: ${params[0].name}<br/>${xLabel}: ${params[0].value}`;},},// 图例配置legend: {show: true, // 是否显示图例data: [yLabel], // 图例数据(与 series.name 对应)left: 'right', // 图例位置(右侧)textStyle: {fontSize: 18, // 图例字体大小color: '#333', // 图例字体颜色},},// 网格配置grid: {left: '10%', // 网格左侧距离right: '10%', // 网格右侧距离bottom: '15%', // 网格底部距离top: '15%',containLabel: true, // 是否包含坐标轴标签},// X 轴配置xAxis: {type: 'category', // 坐标轴类型(类目轴)data: [], // 类目数据axisLabel: {fontSize: 18, // 标签字体大小color: '#333', // 标签字体颜色rotate: 0, // 标签旋转角度interval: 0, // 强制显示所有标签},axisLine: {lineStyle: {color: '#333', // 坐标轴线颜色width: 2, // 坐标轴线宽度},},axisTick: {show: true, // 是否显示坐标轴刻度alignWithLabel: true, // 刻度与标签对齐},name: xLabel, // 坐标轴名称nameLocation: 'center', // 坐标轴名称位置(居中)nameGap: 50, // 坐标轴名称与轴线的距离nameTextStyle: {fontSize: 18, // 坐标轴名称字体大小color: '#333', // 坐标轴名称字体颜色},},// Y 轴配置yAxis: {type: 'value', // 坐标轴类型(数值轴)axisLabel: {fontSize: 18, // 标签字体大小color: '#333', // 标签字体颜色},axisLine: {lineStyle: {color: '#333', // 坐标轴线颜色width: 2, // 坐标轴线宽度},},axisTick: {show: true, // 是否显示坐标轴刻度},splitLine: {show: true, // 是否显示分割线lineStyle: {color: '#eee', // 分割线颜色type: 'dashed', // 分割线类型(虚线)},},name: yLabel, // 坐标轴名称nameLocation: 'center', // 坐标轴名称位置(居中)nameGap: 50, // 坐标轴名称与轴线的距离nameTextStyle: {fontSize: 18, // 坐标轴名称字体大小color: '#333', // 坐标轴名称字体颜色},},// 数据系列配置series: [{name: yLabel, // 系列名称(与图例对应)type: 'bar', // 图表类型(柱状图)data: [], // 数据值barWidth: 'auto', // 柱状图宽度(自动计算)barGap: '5px', // 两个柱子之间的宽度label: {show: true, // 是否显示标签position: 'top', // 标签位置(柱状图顶部)fontSize: 18, // 标签字体大小color: '#333', // 标签字体颜色formatter: '{c}', // 标签内容格式(显示数据值)},itemStyle: {color: '#5470C6', // 柱状图颜色borderColor: '#333', // 柱状图边框颜色borderWidth: 1, // 柱状图边框宽度},},],},};},mounted() {this.initChart();window.addEventListener('resize', this.handleResize);},beforeDestroy() {window.removeEventListener('resize', this.handleResize);if (this.chartInstance) this.chartInstance.dispose();},methods: {initChart() {const dom = this.$refs.chartContainer;if (!dom) {console.error('Chart container not found!');return;}this.chartInstance = echarts.init(dom);const mergedOptions = this.generateOptions();console.log('initChart:', mergedOptions); // 打印 mergedOptionsthis.chartInstance.setOption(mergedOptions);},generateOptions() {let mergedOptions = { ...this.defaultOptions };if (Object.keys(this.options).length > 0) {// 方式一:使用用户自定义的 optionsmergedOptions = this.options;} else if (this.data?.x?.length > 0 && this.data?.y?.length > 0) {// 方式二:使用默认配置,填充 datamergedOptions.xAxis.data = this.data.x;mergedOptions.series[0].data = this.data.y;}console.log('generateOptions:', mergedOptions); // 打印 mergedOptionsreturn mergedOptions;},handleResize() {this.chartInstance?.resize();},},watch: {options: {deep: true,handler() {if (this.chartInstance) {const mergedOptions = this.generateOptions();this.chartInstance.setOption(mergedOptions, { notMerge: true }); // 强制更新}},},data: {deep: true,handler() {if (this.chartInstance) {const mergedOptions = this.generateOptions();this.chartInstance.setOption(mergedOptions, { notMerge: true }); // 强制更新}},},},
};
</script>

折线图组件

<template><div ref="chartContainer" :style="{ width: width, height: height }"></div>
</template><script>
import * as echarts from 'echarts';export default {name: 'ELineChart',props: {title: { type: String, default: "折线图" },xLabel: { type: String, default: "" },yLabel: { type: String, default: "" },options: { type: Object, default: () => ({}) }, // 自定义optionsdata: { type: Object, default: () => ({}) }, // 调用方式{x:[],y:[]}width: { type: String, default: '100%' },height: { type: String, default: '400px' },},data() {let xLabel = this.xLabellet yLabel = this.yLabelreturn {chartInstance: null,defaultOptions: {// 标题配置title: {text: this.title, // 标题文本left: 'center', // 标题位置(居中)top: '0px', // 标题距离图表顶部 20pxtextStyle: {fontSize: 25, // 标题字体大小fontWeight: 'bold', // 标题字体加粗color: '#333', // 标题字体颜色},},// 提示框配置tooltip: {trigger: 'axis', // 触发方式(坐标轴触发)backgroundColor: 'rgba(50, 50, 50, 0.7)', // 提示框背景颜色borderColor: '#333', // 提示框边框颜色borderWidth: 1, // 提示框边框宽度padding: 10, // 提示框内边距textStyle: {fontSize: 18, // 提示框字体大小color: '#fff', // 提示框字体颜色},formatter: function (params) {// 自定义提示框内容return `${yLabel}: ${params[0].name}<br/>${xLabel}: ${params[0].value}`;},},// 图例配置legend: {show: true, // 是否显示图例data: [yLabel], // 图例数据(与 series.name 对应)left: 'right', // 图例位置(右侧)textStyle: {fontSize: 18, // 图例字体大小color: '#333', // 图例字体颜色},},// 网格配置grid: {left: '10%', // 网格左侧距离right: '10%', // 网格右侧距离bottom: '15%', // 网格底部距离top: '15%',containLabel: true, // 是否包含坐标轴标签},// X 轴配置xAxis: {type: 'category', // 坐标轴类型(类目轴)data: [], // 类目数据axisLabel: {fontSize: 18, // 标签字体大小color: '#333', // 标签字体颜色rotate: 0, // 标签旋转角度interval: 0, // 强制显示所有标签},axisLine: {lineStyle: {color: '#333', // 坐标轴线颜色width: 2, // 坐标轴线宽度},},axisTick: {show: true, // 是否显示坐标轴刻度alignWithLabel: true, // 刻度与标签对齐},name: xLabel, // 坐标轴名称nameLocation: 'center', // 坐标轴名称位置(居中)nameGap: 50, // 坐标轴名称与轴线的距离nameTextStyle: {fontSize: 18, // 坐标轴名称字体大小color: '#333', // 坐标轴名称字体颜色},},// Y 轴配置yAxis: {type: 'value', // 坐标轴类型(数值轴)axisLabel: {fontSize: 18, // 标签字体大小color: '#333', // 标签字体颜色},axisLine: {lineStyle: {color: '#333', // 坐标轴线颜色width: 2, // 坐标轴线宽度},},axisTick: {show: true, // 是否显示坐标轴刻度},splitLine: {show: true, // 是否显示分割线lineStyle: {color: '#eee', // 分割线颜色type: 'dashed', // 分割线类型(虚线)},},name: yLabel, // 坐标轴名称nameLocation: 'center', // 坐标轴名称位置(居中)nameGap: 50, // 坐标轴名称与轴线的距离nameTextStyle: {fontSize: 18, // 坐标轴名称字体大小color: '#333', // 坐标轴名称字体颜色},},// 数据系列配置series: [{name: yLabel, // 系列名称(与图例对应)type: 'line', // 图表类型(折线图)data: [], // 数据值label: {show: true, // 是否显示标签position: 'top', // 标签位置(折线图顶部)fontSize: 18, // 标签字体大小color: '#333', // 标签字体颜色formatter: '{c}', // 标签内容格式(显示数据值)},itemStyle: {color: '#5470C6', // 折线图颜色borderColor: '#333', // 折线图边框颜色borderWidth: 1, // 折线图边框宽度},lineStyle: {color: '#5470C6', // 折线颜色width: 2, // 折线宽度},symbol: 'circle', // 数据点形状symbolSize: 8, // 数据点大小},],},};},mounted() {this.initChart();window.addEventListener('resize', this.handleResize);},beforeDestroy() {window.removeEventListener('resize', this.handleResize);if (this.chartInstance) this.chartInstance.dispose();},methods: {initChart() {const dom = this.$refs.chartContainer;if (!dom) {console.error('Chart container not found!');return;}this.chartInstance = echarts.init(dom);const mergedOptions = this.generateOptions();console.log('initChart:', mergedOptions); // 打印 mergedOptionsthis.chartInstance.setOption(mergedOptions);},generateOptions() {let mergedOptions = { ...this.defaultOptions };if (Object.keys(this.options).length > 0) {// 方式一:使用用户自定义的 optionsmergedOptions = this.options;} else if (this.data?.x?.length > 0 && this.data?.y?.length > 0) {// 方式二:使用默认配置,填充 datamergedOptions.xAxis.data = this.data.x;mergedOptions.series[0].data = this.data.y;}console.log('generateOptions:', mergedOptions); // 打印 mergedOptionsreturn mergedOptions;},handleResize() {this.chartInstance?.resize();},},watch: {options: {deep: true,handler() {if (this.chartInstance) {const mergedOptions = this.generateOptions();this.chartInstance.setOption(mergedOptions, { notMerge: true }); // 强制更新}},},data: {deep: true,handler() {if (this.chartInstance) {const mergedOptions = this.generateOptions();this.chartInstance.setOption(mergedOptions, { notMerge: true }); // 强制更新}},},},
};
</script>

饼图组件

<template><div ref="chartContainer" :style="{ width: width, height: height }"></div>
</template><script>
import * as echarts from 'echarts';export default {name: 'EPieChart',props: {title: { type: String, default: "饼图" },options: { type: Object, default: () => ({}) },data: { type: Object, default: () => ([]) },// 调用方式 [{ value: 1048, name: '测量值1' },...]width: { type: String, default: '100%' },height: { type: String, default: '400px' },},data() {return {chartInstance: null,defaultOptions: {// 标题配置title: {text: this.title, // 标题文本left: 'center', // 标题位置(居中)top: '0px', // 标题距离图表顶部 20pxtextStyle: {fontSize: 25, // 标题字体大小fontWeight: 'bold', // 标题字体加粗color: '#333', // 标题字体颜色},},// 提示框配置tooltip: {trigger: 'item', // 触发方式(数据项触发)backgroundColor: 'rgba(50, 50, 50, 0.7)', // 提示框背景颜色borderColor: '#333', // 提示框边框颜色borderWidth: 1, // 提示框边框宽度padding: 10, // 提示框内边距textStyle: {fontSize: 18, // 提示框字体大小color: '#fff', // 提示框字体颜色},formatter: function (params) {// 自定义提示框内容return `${params.name}: ${params.value} (${params.percent}%)`;},},// 图例配置legend: {show: true, // 是否显示图例left: 'right', // 图例位置(右侧)textStyle: {fontSize: 18, // 图例字体大小color: '#333', // 图例字体颜色},},// 数据系列配置series: [{name: '频数', // 系列名称(与图例对应)type: 'pie', // 图表类型(饼图)radius: '50%', // 饼图半径(50%表示占容器的一半)data: [], // 数据值label: {show: true, // 是否显示标签fontSize: 18, // 标签字体大小color: '#333', // 标签字体颜色formatter: '{b}: {c} ({d}%)', // 标签内容格式(显示名称、值和百分比)},itemStyle: {borderColor: '#fff', // 饼图边框颜色borderWidth: 2, // 饼图边框宽度},emphasis: {// 高亮样式label: {show: true,fontSize: 20,fontWeight: 'bold',},itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)',},},},],},};},mounted() {this.initChart();window.addEventListener('resize', this.handleResize);},beforeDestroy() {window.removeEventListener('resize', this.handleResize);if (this.chartInstance) this.chartInstance.dispose();},methods: {initChart() {const dom = this.$refs.chartContainer;if (!dom) {console.error('Chart container not found!');return;}this.chartInstance = echarts.init(dom);const mergedOptions = this.generateOptions();console.log('initChart:', mergedOptions); // 打印 mergedOptionsthis.chartInstance.setOption(mergedOptions);},generateOptions() {let mergedOptions = { ...this.defaultOptions };if (Object.keys(this.options).length > 0) {// 方式一:使用用户自定义的 optionsmergedOptions = this.options;} else if (this.data?.length > 0) {// 方式二:使用默认配置,填充 datamergedOptions.series[0].data = this.data;}console.log('generateOptions:', mergedOptions); // 打印 mergedOptionsreturn mergedOptions;},handleResize() {this.chartInstance?.resize();},},watch: {options: {deep: true,handler() {if (this.chartInstance) {const mergedOptions = this.generateOptions();this.chartInstance.setOption(mergedOptions, { notMerge: true }); // 强制更新}},},data: {deep: true,handler() {if (this.chartInstance) {const mergedOptions = this.generateOptions();this.chartInstance.setOption(mergedOptions, { notMerge: true }); // 强制更新}},},},
};
</script>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词