👉公共组件部分
注意:
1.随机生成id作为唯一标识符,用于区分不同模块的调用
2.合并对象时不能用扩展运算符或者assign()方法,而是使用merge(),进行深拷贝合并
<template>
<div :id="`linechart${id}`" class="line_chart" />
</template>
<script setup lang="ts">
import {
ref,
onMounted,
onUnmounted,
defineProps,
withDefaults
} from 'vue'
import * as echarts from 'echarts'
import { merge } from 'lodash'
// 接受props里的属性值
interface Props {
optionData: any,
}
const props = withDefaults(defineProps<Props>(), {
optionData: Object
})
// 初始化图表
let lineChart: any = null
// 图表公共样式配置
const options:any = {
title: {
text: '折线公共组件示例'
},
xAxis: {
type: 'category',
boundaryGap: false
},
yAxis: {
type: 'value'
},
series: [
{
type: 'line',
smooth: true
}
]
}
// 绘制图表
const drawChart = (): void => {
// 合并公共配置和传入的定制化配置
const lineOption = merge(options, props.optionData)
// 设置配置属性
lineChart.setOption(lineOption)
}
// 随机生成唯一的五位id,用于区别不同页面的调用
const id = ref<string>((Math.random() * 1e6).toString().substr(0, 5))
/**
* 图标重绘
* @returns {void}
*/
const reSize = ():void => {
lineChart.resize()
}
// 挂载图表
onMounted(() => {
const container: HTMLElement | Element | null | any = document.querySelector(`#linechart${id.value}`)
lineChart = echarts.init(container)
window.addEventListener('resize', reSize)
drawChart()
})
// 销毁图标
onUnmounted(() => {
echarts.dispose(lineChart)
})
<style scoped lang="scss">
.line_chart {
height: 100%;
width: 100%;
}
</style>
👉调用
1.要给表格区域明确设定宽高
2.如果不需要定制化样式,需要写出属性置空(否则赋值时找不到对应属性)
3.引用公共图表组件,并传入配置值
<template>
<!-- 折线图示例 -->
<div class="line_chart_container">
<div class="line_chart_box">
<LineChart :optionData="lineOptions"/>
</div>
<div class="line_chart_box">
<LineChart :optionData="lineChartData"/>
</div>
</div>
</template>
<script setup lang="ts">
import {
ref, reactive, onUnmounted
} from 'vue'
import * as echarts from 'echarts'
import LineChart from '@/components/echartsCom/lineChart.vue'
// 折线数据
const lineData = reactive({
name: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
leg: ['Email', 'Video'],
series: {
email: [120, 132, 101, 134, 90, 230, 210],
video: [150, 232, 201, 154, 190, 330, 410]
}
})
// 定制化折线图表配置
const lineOptions:any = reactive({
title: {
text: '折线定制化组件示例',
textStyle: {
color: 'black',
fontSize: 16
}
},
tooltip: {
trigger: 'axis'
},
legend: {
textStyle: {
color: 'black',
fontSize: 12,
padding: 5
},
icon: 'rect',
itemHeight: 10,
itemWidth: 10,
itemGap: 15,
right: 0,
align: 'left'
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
},
series: [
{
name: 'Email',
type: 'line',
stack: 'Total'
},
{
name: 'Video',
type: 'line',
stack: 'Total'
}
]
})
// 无需定制化配置,需要写出属性置空即可
const lineChartData = reactive({
xAxis: {},
yAxis: {},
series: [
{}
]
})
// 给图表赋值,并作为属性参数传给图表公共组件
const setChartData = ():void => {
// 折线图数据赋值
lineOptions.xAxis.data = lineData.name
lineOptions.legend.data = lineData.leg
lineOptions.series[0].data = lineData.series.email
lineOptions.series[1].data = lineData.series.video
lineChartData.xAxis.data = lineData.name
lineChartData.series[0].data = lineData.series.email
}
setChartData()
</script>
<style scoped lang="scss">
#demo-container {
width:100%;
height: 100%;
padding:20px;
.line_chart_container {
display:flex;
flex-direction: column;
.line_chart_box {
width: 400px;
height: 400px;
}
}
}
</style>
👍实现效果
总结:以上将图表的初始化以及配置销毁等方法都封装在公共组件中,而属性配置暴露处理作为动态参数,更有利与代码的维护。如果系统的可复用性高,可以将公共配置尽可能扩展,同时图表赋值这一部分也可以封装在公共组件中。