项目-03-封装echarts组件并使用component动态加载组件
需求
- 由于需要多次用到echarts,需要封装一个echarts组件
- 动态加载echarts组件
场景+代码
场景:
- 在 test.vue 里调用 echarts 组件,test.vue 会将 echarts 需要的数据传给它
- echarts 封装目录如下:其中 app-Echarts 中的 index.vue 将会被注册为【全局组件】,名字为AppEcharts
test.vue
<template>
<div v-for="(item, index) in statisticsType" :key="index">
<AppEcharts :option="item.option" type="line" :id="item.id"></AppEcharts>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
const statisticsType = computed(() => {
{
id: 'id1',
name: '用户总数',
icon: 'app-user',
background: '#EBF1FF',
color: '#3370FF',
sum: [100, 200],
option: { // options里就是echarts图表需要的数据,大家可以自己准备
title: '用户总数',
xDatas: ['2025-1-1', '2025-1-12'],
yDatas: [
{
name: '用户总数',
type: 'line',
area: true,
data: [...]
},
{
name: '用户新增数',
type: 'line',
area: true,
data: [...]
}
]
}
},
})
</script>
/src/components/app-Echarts/index.vue
<template>
<component
:is="typeComponentMap[props.type]"
:option="option"
:id="props.id"
/>
</template>
<script setup lang="ts">
import line from './components/LineEcharts.vue'
defineOptions({ name: 'AppEcharts'})
const props = defineProps({
option: {
type: Object,
required: true
},
type: {
type: String,
default: 'line'
},
id: {
type: String,
required: true
}
})
const typeComponentMap = { line } as any // 将typeComponentMap断言为any
</script>
<style lang="scss" scoped></style>
/src/components/app-Echarts/components/LineEcharts.vue
<template>
<div ref="PieChartRef" :id="props.id" :style="{ height: props.heigth, width: props.width}"></div>
</template>
<script setup lang="ts">
import { nextTick, onMounted, watch } from 'vue';
import * as echarts from 'echarts'
const props = defineProps({
option: {
type: Object,
required: true
},
id: {
type: String,
required: true
},
width: {
type: String,
default: '100%'
},
heigth: {
type: String,
default: '200px'
}
})
const color = ['rgba(82, 133, 255, 1)', 'rgba(255, 207, 47, 1)']
const areaColor = ['rgba(82, 133, 255, 0.2)', 'rgba(255, 207, 47, 0.2)']
function initChart() {
// 获取dom实例
let myChart = echarts?.getInstanceByDom(document.getElementById(props.id)!)
if(myChart === null || myChart === undefined) {
myChart = echarts.init(document.getElementById(props.id))
}
const series: any = []
... // 这里处理了一个options,把里面的部分数据处理成series需要的样子
const option = {
title: {
text: props.option.title, // 标题内容
textStyle: { // 标题样式
fontSize: '16px'
}
},
tooltip: { // 用于设置鼠标悬浮时显示的提示框
trigger: 'axis', // 提示框的触发方式是轴触发
axisPointer: { // 配置坐标指示器
type: 'cross', // 用来设置坐标轴指示器的样式类型
label: { // 用于设置坐标轴指示器的标签样式
backgroundColor: '#6a7985'
}
}
},
legend: { // 用于设置图例项的名称
right: 0,
itemWidth: 8,
textStyle: {
color: '#646A73'
},
icon: 'circle'
},
grid: { // 用于配置图表的网格区域
left: '1%',
right: '1%',
bottom: '0',
top: '18%',
containLabel: true // 坐标轴和图例都被包含在网格区域内
},
xAxis: { // 设置x轴相关属性
type: 'category', // 设置x轴为类目轴,意味着x轴上的数据是类别数据(而不是数值轴)
data: props.option.xDatas // x轴刻度数据
},
yAxis: { // 设置y轴相关属性
type: 'value', // 设置y轴为数值轴,这意味着y轴的值是数字,可以进行数值范围的展示
splitLine: { // 设置y轴的分割线
lineStyle: {
color: '#EFF0F1'
}
}
},
series: series
// series常见属性
// type:图表类型
// name:图表名称
// data:图表数据
// areaStyle:用于设置折线图下方的填充区域样式
// itemStyle:用于设置单个数据项的样式,例如折线图的每个点、柱状图的每根柱子等,有color(颜色)等等
}
myChart.setOption(option, true)
}
function changeChartSize() {
// 调用了图表实例的 resize() 方法,动态调整图表的尺寸以匹配其容器大小。
echarts.getInstanceByDom(document.getElementById(props.id)!)?.resize()
}
watch(
() => props.option,
(val) => {
if (val) {
nextTick(() => {
initChart()
})
}
}
)
onMounted(() => {
nextTick(() => {
initChart()
window.addEventListener('resize', changeChartSize)
})
})
</script>
<style lang="scss" scoped></style>
补充说明
1. typeComponentMap 讲解
**问题:**为什么要单独再写typeComponentMap ?
- 因为这样封装的组件可以通过type指定需要的图表种类
- 我可能会封装多种样式的echarts图表(在上述截图中我只封装了折线图),例如如果我在 /src/components/app-Echarts/components/ 封装了 LineEcharts.vue 和 Column.vue,那么我可以在script里引入这两个组件,然后都加到typeComponentMap中,这样可以通过传递type参数指定需要的echarts图表类型
原文地址:https://blog.csdn.net/m0_64150479/article/details/145232393
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!