如何手撸一个echarts图表组件

55 阅读2分钟

哈喽!这里是苏苏吖~,最近在做项目时,遇到很多图形图表的应用,但是一个一个的去引用显得好笨,再请教了 唐志远 大佬后得到一些感悟,在这里再次回顾一下封装的过程。

原文链接:如何手撸一个echarts图表组件 | 苏苏の休憩小屋 (luckysusu.top)

:cat: 封装方式有很多种,我所做的封装仅仅是方便我自己在项目中使用,所以主要以记录为主,讲解不多。见谅

开始之前

​ 首先,虽然说是在vue3的项目中做的封装,但是基本的封装逻辑是大差不差的。而在我接下来的封装中,封装的逻辑基本是按照 引入依赖——创建钩子函数——定义响应式引用——定义渲染函数——返回对应对象 来进行的。

​ 好啦,请确保已经创建好项目,并安装好了依赖,此处封装的图表库依赖来源于Echarts图形图表库

$ npm install echarts --save

正式开始

不说废话,直接上代码!

首先是useEcharts函数。useEcharts.js

import { ref } from 'vue';
import * as echarts from 'echarts';

//定义useEcharts函数,接受chartDom和options两个参数。为什么传入options参数可以看看echarts官方文档。
//因为每个图表显示的什么图主要就是由options的配置来决定。
export default function useECharts(chartDom, options) {
    const chartInstance = ref(null); // 响应式引用

    const renderChart = () => { //renderchart函数用于渲染图表
        if (!chartInstance.value) {
            chartInstance.value = echarts.init(chartDom.value);
        }

        chartInstance.value.setOption(options);
    };

    return {
        chartInstance,
        renderChart,
    };
}

定义通用组件模版Echarts.vue

<template>
	<!-- 定义div元素作为图标容器,通过ref获取元素,:style响应式样式 -->
    <div ref="chart" :style="{ width: width, height: height }"></div> 
</template>
  
<script>
import { ref, onMounted, onUnmounted } from 'vue';
import useECharts from '@/hooks/useECharts';

export default {
    props: { //用于配置图表的选项以及指定图标容器的宽高
        chartOptions: Object,
        width: String,
        height: String,
    },
    setup(props) {
        const chart = ref(null); //通过ref获取页面元素

        const { chartInstance, renderChart } = useECharts(chart, props.chartOptions);

        onMounted(() => {
            renderChart(); //在onMounted钩子中调用renderChart函数渲染图标
        });

        onUnmounted(() => { //在onUmmounted钩子中,当组件销毁时,判断图标是否存在。如果存在的调用dispose清理
            if (chartInstance.value) {
                //解释一下为什么会有dispose方法。因为echarts.init返回的实例已经有 dispose方法了。
                //所以,只需要直接调用chartInstance.value.dispose()就行 
                chartInstance.value.dispose();
            }
        });

        return {
            chart,
        };
    },
};
</script>
  
<style lang="scss" scoped></style>

真正的使用页面:demo.vue

<template>
    <el-card>
        <template #header>
            <span class="font-semibold">设备状态</span>
        </template>
        <Echarts :chartOptions="chartOptions" :width="chartWidth" :height="chartHeight"></Echarts>
    </el-card>
</template>

<script setup>
import { ref } from 'vue';
import Echarts from '@/components/Echarts.vue';

const chartWidth = ref('100%');
const chartHeight = ref('320px')

const chartOptions = {
    tooltip: {
        trigger: 'item',
    },
    legend: {
        left: 'center',
    },
    series: [
        {
            name: '设备状态',
            type: 'pie',
            radius: ['25%', '75%'],
            avoidLabelOverlap: false,
            itemStyle: {
                borderRadius: 8,
                borderColor: '#fff',
                borderWidth: 2
            },
            label: {
                show: false,
                position: 'center'
            },
            emphasis: {
                label: {
                    show: true,
                    fontSize: '20',
                    fontWeight: 'bold'
                }
            },
            labelLine: {
                show: false,
            },
            data: [
                { value: '27', name: '完美' },
                { value: '17', name: '优秀' },
                { value: '20', name: '良好' },
                { value: '10', name: '及格' },
                { value: '5', name: '不及格' },
                { value: '1', name: '差' },
            ]
        }
    ]
}

</script>

<style lang="scss" scoped></style>

​ 欧克,以上就是封装一个echarts组件的代码过程,十分简单,没有花里胡哨。当然,可能还存在一些漏洞或者不完美的地方,欢迎指正!我也会不断进步哒!我是苏苏,一枚二次元码农:hibiscus:。