uniapp x + vue3 实现echarts图表

一、引入echarts组件

在Dcloud插件市场下载echarts插件:https://ext.dcloud.net.cn/plugin?id=4899

下载解压后的文件结构如下图所示:

1、将提供的 components 文件复制到你项目对应的components目录中。

目录结构示意图如下:

2、将提供的static / app下的文件复制到你项目对应的 static 目录中。

3、打开echarts官网(https://echarts.apache.org/zh/download.html),下载定制图表。

下载后得到echarts.min.js文件,替换原插件中的echarts.min.js(存放于static文件夹下)。

二、引入并实现Echarts图表

1、引入,参考:https://gitee.com/liangei/lime-echart#vue3

2、实现

父组件:

html 复制代码
<CustomEcharts 
    v-if="progressData.course_finish_data" 
	:dataList="progressData.course_finish_data"
	@getFinishIds="getFinishIds"
/>
javascript 复制代码
<script setup>
    import CustomEcharts from "./components/customEcharts.uvue";
    
    const getFinishIds = async (val:string) => {
		console.log(val, '获取的ids')
	}
</script>

子组件:

html 复制代码
<template>
	<view class="chart_content_item">
		<LEchart ref="chartRef"></LEchart>
	</view>
</template>

<script lang="ts" setup>
import LEchart from "./l-echart/l-echart.vue";
import { ref, onMounted, watch } from "vue"
const echarts = require('../static/echarts.min.js')
const chartRef = ref(null);
const chartInstance = ref(null); // 保存图表实例

const props = defineProps({
	dataList: Array
});
const emits = defineEmits(['getFinishIds']); // 定义自定义事件

const new_data = Object.values(props.dataList).map(item => ({
	value: item.finish_num,
	name: item.title,
	ids: item.finish_id_str,
	// 可以添加其他需要传递的数据
	itemData: item
}))

const pieOption = {
	tooltip: {
		trigger: 'item',
		formatter: function(params) {
			return `${params.name}: \n ${params.value}人`;
		}
	},
	legend: {
		top: '5%',
		left: 'center'
	},
	series: [
		{
			name: '课程完成情况',
			type: 'pie',
			radius: ['40%', '70%'], // 饼图的半径
			center: ['50%', '90%'], // 饼图的中心(圆心)坐标,[横坐标,纵坐标]。
			startAngle: 180, // 起始角度,支持范围[0, 360]
			endAngle: 360, // 结束角度,自动计算
			itemStyle: {
				color: function(params) {
					const colorList = [
						'#0ca8df', '#ffd10a', '#fb628b',
						'#785db0', '#5070dd', '#b6d634',
						'#56597a', '#ff9a4d'
					];
					return colorList[params.dataIndex % colorList.length];
				}
			},
			// data: new_data
			data: [
					{ value: 1048, name: '完成1-3门课程人数', ids:"1" },
					{ value: 735, name: '完成3-6门课程人数', ids:"1,2" },
					{ value: 580, name: '完成6-9门课程人数', ids:"3,4" }
				],
			// 高亮样式
			emphasis: {
				itemStyle: {
					shadowBlur: 10,
					shadowOffsetX: 0,
					shadowColor: 'rgba(0, 0, 0, 0.5)'
				},
				label: {
					show: true,
					fontSize: '16',
					fontWeight: 'bold'
				}
			},
			label: {
				formatter: '{b}: {c}人 ({d}%)',
				fontSize: 12
			}
		}
	]
};

// 初始化图表
const initChart = () => {
	if (!chartRef.value) return;
	
	chartRef.value.init(echarts, (chart) => {
		chartInstance.value = chart;
		chart.setOption(pieOption);
		
		// 绑定点击事件
		bindChartEvents(chart);
	});
};

// 绑定图表事件
const bindChartEvents = (chart) => {
	// 监听饼图点击事件
	chart.on('click', function(params) {
		const clickedData = params.data; // 获取点击项的数据
		const ids = clickedData.ids; // 获取ids
		emits('getFinishIds', ids); // 传参
	});
	
	// 监听其他事件(可选)
	chart.on('mouseover', function(params) {
		// 鼠标悬停事件
		console.log('鼠标悬停:', params.data);
	});
	
	chart.on('mouseout', function(params) {
		// 鼠标移出事件
		console.log('鼠标移出');
	});
};

onMounted(() => {
	setTimeout(() => {
		initChart();
	}, 300);
});

// 监听数据变化
watch(() => props.dataList, (newData) => {
	if (!chartInstance.value) return;
	
	// 更新数据
	const updatedData = Object.values(newData).map(item => ({
		value: item.finish_num,
		name: item.title,
		ids: item.finish_id_str,
		itemData: item
	}));
	
	// 更新图表
	chartInstance.value.setOption({
		series: [{
			data: updatedData
		}]
	});
}, { deep: true });

// 监听配置变化
watch(() => pieOption, (newOption) => {
	if (chartInstance.value) {
		chartInstance.value.setOption(newOption);
	}
}, { deep: true });

// 暴露方法给父组件
defineExpose({
	getSelectedData: () => {
		if (!chartInstance.value) return null;
		// 可以通过其他方式获取当前选中的数据
	},
	refreshChart: () => {
		if (chartInstance.value) {
			chartInstance.value.resize();
		}
	}
});
</script>

<style lang="scss" scoped>
.chart_content_item {
	width: 100%;
	height: 150px;
}
</style>

最终实现效果:

相关推荐
We་ct15 分钟前
LeetCode 205. 同构字符串:解题思路+代码优化全解析
前端·算法·leetcode·typescript
2301_812731411 小时前
CSS3笔记
前端·笔记·css3
ziblog1 小时前
CSS3白云飘动动画特效
前端·css·css3
越努力越幸运5081 小时前
CSS3学习之网格布局grid
前端·学习·css3
半斤鸡胗1 小时前
css3基础
前端·css
ziblog1 小时前
CSS3创意精美页面过渡动画效果
前端·css·css3
akangznl1 小时前
第四章 初识css3
前端·css·css3·html5
会豪1 小时前
深入理解 CSS3 滤镜(filter):从基础到实战进阶
前端·css·css3
头顶一只喵喵1 小时前
CSS3进阶知识:CSS3盒子模型,box-sizing:content-box和box-sizing:border-box的讲解
前端·css·css3
小飞大王6661 小时前
css进阶用法
前端·css