在Vue3中如何更优雅的使用echart图表详解

目录
  • 前言
  • 封装思路
    • 引入模块
    • 封装功能
    • 使用例子
  • 总结

前言

在大屏可视化项目中,我们常常需要用到很多的图表组件,通常你会编写很多的option对图表进行渲染,以及引入它们所需的一些组件并使用echart.use。

在Vue2中我们常常把可复用的组件单独抽离出来,再通过props、emit等方法向复用组件中传入组件所需数据,而在Vue3中我们可以将一些逻辑功能写成hook进行抽离和复用再传入到视图中,这会不仅让你的组件中的代码更加优雅而且阅读性更强。

封装思路

引入模块

我们先创建lib.ts文件,用于将echart图表中所需要用到组件全部引入进来并导出。

由于引入的模块过多,所以我们把它引入的模块的代码抽离出来,增加代码的可阅读性

// lib.ts
import * as echarts from 'echarts/core';

import {
    BarChart,
    LineChart,
    PieChart,
    MapChart,
    PictorialBarChart,
    RadarChart,
    ScatterChart
} from 'echarts/charts';

import {
    TitleComponent,
    TooltipComponent,
    GridComponent,
    PolarComponent,
    AriaComponent,
    ParallelComponent,
    LegendComponent,
    RadarComponent,
    ToolboxComponent,
    DataZoomComponent,
    VisualMapComponent,
    TimelineComponent,
    CalendarComponent,
    GraphicComponent
} from 'echarts/components';

echarts.use([
    LegendComponent,
    TitleComponent,
    TooltipComponent,
    GridComponent,
    PolarComponent,
    AriaComponent,
    ParallelComponent,
    BarChart,
    LineChart,
    PieChart,
    MapChart,
    RadarChart,
    PictorialBarChart,
    RadarComponent,
    ToolboxComponent,
    DataZoomComponent,
    VisualMapComponent,
    TimelineComponent,
    CalendarComponent,
    GraphicComponent,
    ScatterChart
]);

export default echarts;

封装功能

在同级目录下创建一个useChart.ts文件,这是我们复用echart图表hook文件。

封装功能如下:

  • 监听图表元素变化及视图,自动重新渲染图表适应高度
  • 可传入主题、渲染模式(SVG、Canvas)
  • loading效果
import { nextTick, onMounted, onUnmounted, Ref, unref } from "vue";
import type { EChartsOption } from 'echarts';
import echarts from "./lib";
import { SVGRenderer, CanvasRenderer } from "echarts/renderers";
import { RenderType, ThemeType } from "./types";

export default function useChart(elRef: Ref<HTMLDivElement>, autoChartSize = false, animation: boolean = false, render: RenderType = RenderType.SVGRenderer, theme: ThemeType = ThemeType.Default) {
    // 渲染模式
    echarts.use(render === RenderType.SVGRenderer ? SVGRenderer : CanvasRenderer)
    // echart实例
    let chartInstance: echarts.ECharts | null = null;

    // 初始化echart
    const initCharts = () => {
        const el = unref(elRef)
        if (!el || !unref(el)) {
            return
        }
        chartInstance = echarts.init(el, theme);
    }

    // 更新/设置配置
    const setOption = (option: EChartsOption) => {
        nextTick(() => {
            if (!chartInstance) {
                initCharts();
                if (!chartInstance) return;
            }

            chartInstance.setOption(option)
            hideLoading()
        })

    }

    // 获取echart实例
    function getInstance(): echarts.ECharts | null {
        if (!chartInstance) {
            initCharts();
        }
        return chartInstance;
    }

    // 更新大小
    function resize() {
        chartInstance?.resize();
    }

    // 监听元素大小
    function watchEl() {
        // 给元素添加过渡
        if (animation) { elRef.value.style.transition = 'width 1s, height 1s' }
        const resizeObserver = new ResizeObserver((entries => resize()))
        resizeObserver.observe(elRef.value);
    }

    // 显示加载状
    function showLoading() {
        if (!chartInstance) {
            initCharts();
        }
        chartInstance?.showLoading()
    }
    // 显示加载状
    function hideLoading() {
        if (!chartInstance) {
            initCharts();
        }
        chartInstance?.hideLoading()
    }

    onMounted(() => {
        window.addEventListener('resize', resize)
        if (autoChartSize) watchEl();
    })

    onUnmounted(() => {
        window.removeEventListener('resize', resize)
    })

    return {
        setOption,
        getInstance,
        showLoading,
        hideLoading
    }
}
// types.ts
export enum RenderType {
    SVGRenderer = 'SVGRenderer',
    CanvasRenderer = 'SVGRenderer'
}
export enum ThemeType {
    Light = 'light',
    Dark = 'dark',
    Default = 'default'
}

有了以上封装好之后的代码,我们在组件中使用echart图表库时将会更加简单而高效。

使用例子

// index.vue
<template>
    <div ref="chartEl" :style="{ width: `300px`, height: `300px` }"></div>
</template>

<script setup lang="ts">
import { onMounted, Ref, ref, computed, nextTick } from "vue";
import type { EChartsOption } from 'echarts'
import useChart, { RenderType, ThemeType } from '../../useChart'
import axios from 'axios'

const option = computed<EChartsOption>(() => ({
   // ...chart option
}))

const chartEl = ref<HTMLDivElement | null>(null)

const {
    setOption,
    showLoading
} = useChart(chartEl as Ref<HTMLDivElement>, true, true, RenderType.SVGRenderer, ThemeType.Dark)

onMounted(() => {
    nextTick(() => {
    	// 显示loading
        showLoading()
        // 假装有网络请求 ...
        // 渲染图表
        setOption(option.value);
    })
})
</script>

Github仓库地址(含例子):github.com/QC2168/useC…

总结

到此这篇关于在Vue3中如何更优雅的使用echart图表的文章就介绍到这了,更多相关Vue3使用echart图表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue2 vue3中使用Echarts详细

    目录 1.安装 2.vue2中使用Echarts 在main.js文件中 给定一个容器 3.vue3中使用Echarts 在根组件里引入echart,一般是App.vue 在需要使用的页面,定义div 然后在需要使用到Echarts的页面inject 1.安装 npm install echarts --save 2.vue2中使用Echarts 在main.js文件中 // 引入echarts import echarts from 'echarts' Vue.prototype.$echar

  • 使用Vue3和Echarts 5绘制带有立体感流线中国地图(推荐收藏!)

    目录 本文绘制的地图效果图如下: 一.Echarts 使用五部曲 1.下载并引入 echarts 2.准备容器 3.实例化 echarts 对象 4.指定配置项和数据 5.给 echarts 对象设置配置项 二.开始绘制流线中国地图 第一步:先绘制一个中国地图 第二步:添加流线 第三步:添加立体投影 总结 本文绘制的地图效果图如下: 一.Echarts 使用五部曲 1.下载并引入 echarts Echarts 已更新到了 5.0 版本,安装完记得检查下自己的版本是否是 5.0 . npm in

  • vue3.0+echarts实现立体柱图

    前言: vue3.0实现echarts立体柱图 实现效果: 实现步骤: 1.安装echarts cnpm i --save echarts 2.页面定义容器 <template> <div ref="echart" class="echartDiv"></div> </template> 3.js中引入echarts import * as echarts from 'echarts'; 组件完整源码: <tem

  • 在Vue3中如何更优雅的使用echart图表详解

    目录 前言 封装思路 引入模块 封装功能 使用例子 总结 前言 在大屏可视化项目中,我们常常需要用到很多的图表组件,通常你会编写很多的option对图表进行渲染,以及引入它们所需的一些组件并使用echart.use. 在Vue2中我们常常把可复用的组件单独抽离出来,再通过props.emit等方法向复用组件中传入组件所需数据,而在Vue3中我们可以将一些逻辑功能写成hook进行抽离和复用再传入到视图中,这会不仅让你的组件中的代码更加优雅而且阅读性更强. 封装思路 引入模块 我们先创建lib.ts

  • Python中更优雅的日志记录方案详解

    目录 常见使用 loguru 安装 基本使用 详细使用 在 Python 中,一般情况下我们可能直接用自带的 logging 模块来记录日志,包括我之前的时候也是一样.在使用时我们需要配置一些 Handler.Formatter 来进行一些处理,比如把日志输出到不同的位置,或者设置一个不同的输出格式,或者设置日志分块和备份.但其实个人感觉 logging 用起来其实并不是那么好用,其实主要还是配置较为繁琐. 常见使用 首先看看 logging 常见的解决方案吧,我一般会配置输出到文件.控制台和

  • 如何在vue中更优雅的封装第三方组件详解

    目录 一.需求场景描述 二.关键技术点介绍 1.v-bind="$attrs" 2.v-on="$listeners" 三.封装el-image的代码示例 总结 一.需求场景描述 实际开发的时候,为了减少重复造轮子,提高工作效率,节省开发时间成本, 免不了会使用ui组件库,比如在web前端很受欢迎的element-ui. 但有的时候,我们需要在原组件的基础上做些改造,比如一个image组件, 我们需要统一在图片加载失败的时候展示的特定图,每次使用组件都加一遍, 麻烦

  • Java中该如何优雅的使用线程池详解

    目录 为什么要用线程池? 线程池 线程池基本概念 线程池接口定义和实现类 ExecutorService ScheduledExecutorService 线程池工具类 newFixedThreadPool(int nThreads) newCachedThreadPool() newSingleThreadExecutor() newScheduledThreadPool(int corePoolSize) 任务线程池执行过程 如何确认合适的线程数量? 线程池的使用分析 合理配置线程池大小 线

  • vue3中$attrs的变化与inheritAttrs的使用详解

    目录 在vue3中的$attrs的变化 在vue2中的$attrs 父组件的属性直接渲染在根节点上 在vue3中的$attrs的变化 $listeners已被删除合并到$attrs中. $attrs现在包括class和style属性. 也就是说在vue3中$listeners不存在了.vue2中$listeners是单独存在的. 在vue3 $attrs包括class和style属性, vue2中 $attrs 不包含class和style属性. 在vue2中的$attrs 在Vue 2中,at

  • Vue3中Vite和Vue-cli的特点与区别详解

    目录 1. 创建3.0项目 Vite 与 Vue-cli 是什么? Vue-cli 的特点: Vite 的特点: Vite 和 Vue-cli的区别: 总结: 1. 创建3.0项目 vue-cli : 安装并执行 npm init vue@latest 选择项目功能时: 除了第一项的项目名字外,其他可以暂时No cd title npm install npm run dev :运行 npm run build: 打包 (生成一个dist文件夹) vite: 使用vite 体验更快速 npm i

  • Java中利用POI优雅的导出Excel文件详解

    前言 故事是这样开始的: 公司给排了几天的工期,让完成 2 个功能模块的开发.其中有一个场景是这样的,从 Excel 导入数据,要求数据不能重复.用户可以下载导入失败的 Excel 文件. 这样就有 2 种实现 将失败数据存储数据库,需要下载时生成 Excel 下载即可 将失败数据生成 Excel 文件存储文件服务器,然后返回下载链接. 老大要求按方案二进行.好吧,导出 Excel 是再常见不过的功能了,然而总是觉得以前写的不够优雅,所以决定进行简单的封装,以适应简单场景的 Excel 导出.

  • Vue3中SetUp函数的参数props、context详解

    1.setUp函数的第1个参数props setup(props,context){} 第一个参数props: props是一个对象,包含父组件传递给子组件的所有数据. 在子组件中使用props进行接收. 包含配置声明并传入的所有的属性的对象 也就是说:如果你想通过props的方式输出父组件传递给子组件的值. 你需要使用props进行接收配置.即props:{......} 如果你未通过Props进行接受配置,则输出的值是undefined <template> <div class=&

  • Vue3中element-plus全局使用Icon图标的过程详解

    目录 1.安装图标库 2.注册 3.在组件中直接使用 4.在el-menu组件中动态使用 总结 Vue项目中使用Element-plus的Icon图标,包括按钮和动态菜单 1.安装图标库 npm install @element-plus/icons 2.注册 main.ts文件中引入并注册 import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' impo

  • vue3中defineProps传值使用ref响应式失效详解

    子组件接收父组件的传参. 父组件: <template> <Son :data="data"/> </template> <script setup> import { ref } from "vue"; let data = ref('hello') setTimeout(() => { data.value = 'how are you doing' }, 2000) </script> 子组件:

随机推荐