封装的组件
目录
- 封装的组件
- 在项目中使用
BaseChart.vue
<script setup>import {ref,onMounted,onBeforeUnmount,watch,markRaw} from 'vue';import {debounce} from "@/utils"; //节流函数 import * as echarts from "echarts";const emit = defineEmits(['chartClick', 'chartMouseover', 'chartMouseout'])const props = defineProps({option: {type: Object,defined: () => {}},width: {type: String,defined: '100%'}, // 必须指定容器的宽高,否则无法显示。(容器内图表会自动获取父元素宽高)height: {type: String,defined: '100%'},theme: {type: [Object, String],defined: ''},loading: {type: Boolean,defined: false}, // 受控onMouseover: {type: Function,defined: () => {}},onMouseout: {type: Function,defined: () => {}},onClick: {type: Function,defined: () => {}}})const chartRef = ref(null);const chartInstance = ref();const draw = () => {if (chartInstance.value) {// console.log('修改了', props.option);chartInstance.value.setOption(props.option, {notMerge: true});}};const init = () => {if (!chartRef.value) return;// 校验 Dom 节点上是否已经挂载了 ECharts 实例,只有未挂载时才初始化chartInstance.value = echarts.getInstanceByDom(chartRef.value);if (!chartInstance.value) {chartInstance.value = markRaw(echarts.init(chartRef.value, props.theme, {renderer: 'canvas',}));// 绑定鼠标事件:if (props.onMouseover) {chartInstance.value.on('mouseover', (event) => {props.onMouseover(event, chartInstance.value, props.option);});}if (props.onMouseout) {chartInstance.value.on('mouseout', (event) => {props.onMouseout(event, chartInstance.value, props.option);});}if (props.onClick) {chartInstance.value.on('click', (event) => {props.onClick(event, chartInstance.value, props.option);});}chartInstance.value.on('mouseover', (event) => {emit('chartMouseover', event, chartInstance.value, props.option)})chartInstance.value.on('mouseout', (event) => {emit('chartMouseout', event, chartInstance.value, props.option)})chartInstance.value.on('click', (event) => {emit('chartClick', event, chartInstance.value, props.option)})draw();}};// 窗口自适应并开启过渡动画const resize = () => {if (chartInstance.value) {chartInstance.value.resize({animation: {duration: 300}});}};// 自适应防抖优化const debouncedResize = debounce(resize, 500, {maxWait: 800});// 对父组件暴露获取 ECharts 实例的方法,可直接通过实例调用原生函数defineExpose({getInstance: () => chartInstance.value,resize,draw,});watch(props, () => {draw();});// 展示 loading 动画watch(() => props.loading,loading => {loading?chartInstance.value.showLoading() :chartInstance.value.hideLoading();});onMounted(() => {init();window.addEventListener('resize', debouncedResize);});onBeforeUnmount(() => {// 容器被销毁之后,销毁实例,避免内存泄漏chartInstance.value?.dispose();window.removeEventListener('resize', debouncedResize);});
</script><template><div id="echart" ref="chartRef" :style="{ width: props.width, height: props.height }" />
</template>
在项目中使用
注意:如果你要使用渐变颜色还得自己引入echarts
<template><div class="main-box" style="width: 100%;height: 100%;"><!-- :onClick="clickChart" :onMouseout="onMouseout" :onMouseover="onMouseover"--><!-- @chartClick="clickChart" @chartMouseover="chartMouseover" @chartMouseout="chartMouseout" --><!-- 上面有两种点击事件和鼠标事件 都能使用 --><BaseChart @chartClick="clickChart" width="100%" height="100%" :option="chartOptions"></BaseChart></div>
</template><script setup>import BaseChart from '@/components/BaseChart/index.vue'import {requestGet} from '@/api/index.js'import {onMounted,ref} from 'vue'import * as echarts from "echarts";onMounted(() => {initChart();})const chartOptions = ref({})const clickChart = (e, chart, option) => {console.log('图标数据', e);console.log('图标dom', chart);console.log('图标option', option);}const initChart = async () => {chartOptions.value = {grid: {top: '15%',left: '1%',right: '7%',bottom: '0%',containLabel: true,},legend: {top: '0%',right: '10%',itemGap: 50,data: ['产量', '产值'],textStyle: {color: '#f9f9f9',borderColor: '#fff'},},xAxis: [{name: '年',nameGap: 5,type: 'category',axisLine: { //坐标轴轴线相关设置。数学上的x轴show: true,lineStyle: {color: '#999'},},axisLabel: { //坐标轴刻度标签的相关设置color: '#999',},axisTick: {show: false,},data: ['2017', '2018', '2019', '2020', '2021', '2022', '2023', ],}],yAxis: [{type: 'value',min: 0,// max: 140,splitNumber: 7,splitLine: {show: true,lineStyle: {color: '#0a3256'}},axisLine: {show: false,},axisLabel: {// margin: 20,color: '#999',},axisTick: {show: false,},}],tooltip: {trigger: 'axis',},series: [{name: '产量',type: 'line',// smooth: true, //是否平滑曲线显示// symbol:'circle', // 默认是空心圆(中间是白色的),改成实心圆showAllSymbol: true,symbol: 'emptyCircle',// symbolSize: 6,lineStyle: {color: "#28ffb3", // 线条颜色borderColor: '#f0f'},label: {show: false,position: 'top',color: '#fff',},itemStyle: {color: "#28ffb3",lineStyle: {width: 1,type: 'solid' //'dotted'虚线 'solid'实线}},areaStyle: { //区域填充样式//线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0,color: 'rgba(0,154,120,1)'},{offset: 1,color: 'rgba(0,0,0, 0)'}], false),shadowColor: 'rgba(53,142,215, 0.9)', //阴影颜色shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。},data: [393, 438, 485, 631, 689, 824, 987]}, {name: '产值',type: 'bar',barWidth: 15,// tooltip: {// show: false// },label: {show: false,position: 'top',color: '#fff',},itemStyle: {color: "#1cfffb",lineStyle: {width: 1,type: 'solid' //'dotted'虚线 'solid'实线},// barBorderRadius: [30, 30, 0, 0],},}]};}</script><style scoped lang="scss">.main-box {width: 100%;height: 100%;}.main-content {width: 100%;height: 100%;}
</style>```