vue3中如何更优雅的使用echarts?

news2024/11/17 10:26:33

echarts在vue或者react中使用存在的问题

  • 每个图表需要从头到尾写地一遍完整的option配置,这样一来的话就会显得十分的冗余
  • 在同一个项目中,其实不难发现各类图表设计十分相似,甚至是相同,因此我们没必要一直做重复的工作,去写差不多配置的option
  • 再一个就是窗口缩放时的适应问题
  • 那么在项目中如何按需引入echarts图表 减少打包体积的大小就显得尤为重要了

解决方案

  • 统一封装图表组件,统一管理图表配置,做到业务数据和echarts的 option样式配置数据分离
  • 统一解决窗口缩放时的图表的适应问题, 解决窗口缩放引起的echarts图形变形的问题
  • 按需引入echarts图表 减少打包体积的大小,(全量引入按需引入 打包后的体积减少了三分之一)

插件安装:

  • npm/cnpm element-resize-detector -S    动态监听元素尺寸变化,与window的resize事件不同,resize只能监听window的窗口尺寸变化,不能监听某个元素尺寸变化
  • echarts    图表组件库
  • lodash    主要利用其中的 merge 函数,用于将多个对象合并成一个新的对象。具体用法可参考:lodash.merge | Lodash中文文档 | Lodash中文网

封装 echarts 

将 ECharts 的配置封装到插件中,这里我们可以实现:按需引入图表、按需引入图表配置比如提示框,标题等等

然后在 main.js 里进行全局注册,就可以在需要使用的地方很方便快捷的进行使用了

其代码如下:

plugins/echarts.js

// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
import * as echarts from "echarts/core";
// 按需引入折线图、饼状图、柱状图,图表后缀都为 Chart
import { BarChart, PieChart, LineChart } from "echarts/charts";
// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  LegendComponent,
} from "echarts/components";
// 标签自动布局、全局过渡动画等特性
import { LabelLayout, UniversalTransition } from "echarts/features";
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from "echarts/renderers";

// 注册必须的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  LegendComponent,
  BarChart,
  PieChart,
  LineChart,
  LabelLayout,
  UniversalTransition,
  CanvasRenderer,
]);
export default echarts;

main.js

import echarts from './plugins/echarts';


const app = createApp(App);

app.provide("$echarts", echarts);

这样做的优点如下:

  1. 模块化和组织性: 将 ECharts 的配置封装到插件中,使得项目中的 ECharts 相关配置和代码能够按功能模块进行组织和管理。这样做有助于提高代码的可维护性和可读性。

  2. 复用性: 将 ECharts 相关配置封装到插件中,可以在不同的组件中复用相同的配置。这样做有助于减少重复的代码编写,提高开发效率。

  3. 全局性: 将 ECharts 的配置通过 Vue 的 provide/provide API 全局挂载,使得在整个 Vue 应用中都能够方便地使用相同的 ECharts 实例。这样做有助于保持应用中 ECharts 实例的一致性,避免了在不同组件中重复创建 ECharts 实例的问题。

  4. 便捷性: 通过将 ECharts 配置封装到插件中,并通过 provide/provide API 进行全局挂载,可以在 Vue 应用的任意组件中直接使用 $echarts 实例,无需每次都单独引入和配置 ECharts。这样做简化了在 Vue 应用中使用 ECharts 的流程,提高了开发效率。

使用实例

这里以封装一个饼图为例,代码如下

封装饼图组件

在 components 目录下,新建 Echart 文件夹

在 Echart 文件夹下,新建 pie 文件夹,用来封装 pie 组件 和 存放其 option 配置

在 Echart 文件夹下,新建 color.js ,用来放置通用的颜色数组

pie/chartPie.vue

<template>
  <div ref="chartRef" class="chart"></div>
</template>
<script setup>
import { defineProps, ref, onMounted, onUnmounted, watch, inject } from "vue";
import { merge } from "lodash";
import ResizeListener from "element-resize-detector";
import { COLORSARRAY } from "../color.js";
import { BASEOPTIONS } from "./defaultOptions.js";
let echartInstance = null;
// 导入全局挂载的echarts
const echarts = inject("$echarts");

// 使用vue的refs声明dom节点,方便后续操作
const chartRef = ref(null);
const props = defineProps({
  seriesData: {
    type: Array,
    required: true,
    default: () => [],
  },
  // 需要特殊定制的配置
  extraOption: {
    type: Object,
    default: () => ({}),
  },
});
// 监控seriesData的变化,当变化时更新echart视图
watch(
  () => props.seriesData,
  (newVal) => {
    updateChartView();
  },
  {
    // immediate: true,
    deep: true,
  }
);

/**
 * 对chart元素尺寸进行监听,当发生变化时同步更新echart视图
 */
const addChartResizeListener = () => {
  const instance = ResizeListener({
    strategy: "scroll",
    callOnAdd: true,
  });
  instance.listenTo(chartRef.value, () => {
    if (chartRef.value) {
      // chartRef.value.resize();
      echartInstance.resize();
    }
  });
};
/**
 * 当窗口缩放时,echart动态调整自身大小
 */
const handleWindowResize = () => {
  if (chartRef.value) {
    echartInstance.resize();
    // chartRef.value?.resize();
  }
};
const assembleDataToOption = (seriesData) => {
  // 这部分的图例formatter取决于UI要求,如果你的项目中不需要,就可以不写formatter
  // 由于echarts版本的迭代,这里的写法也有稍许改变
  const formatter = (name) => {
    const total = props.seriesData.reduce((acc, cur) => acc + cur.value, 0);
    const data = props.seriesData.find((item) => item.name === name) || {};
    const percent = data.value
      ? `${Math.round((data.value / total) * 100)}%`
      : "0%";
    return `${name} ${percent}`;
  };

  return merge(
    {},
    BASEOPTIONS,
    { color: COLORSARRAY },
    {
      legend: { formatter },
      series: [{ data: props.seriesData }],
    },
    props.extraOption
  );
};
const updateChartView = () => {
  if (!chartRef.value) return;
  const fullOption = assembleDataToOption();
  echartInstance = echarts.init(chartRef.value);
  echartInstance.setOption(fullOption);
};
onMounted(() => {
  // echarts.init(chartRef.value)
  updateChartView();
  window.addEventListener("resize", handleWindowResize);
  addChartResizeListener();
});
onUnmounted(() => {
  window.removeEventListener("resize", handleWindowResize);
});
</script>
<style lang="scss">
.chart {
  width: 100%;
  height: 450px;
}
</style>

pie/defaultOptions.js

// 这里的数据会被深度合并
const BASEOPTIONS = {
  title: {
    text: "产品成功率",
    left: "center",
    padding: 70
  },
  tooltip: {
    trigger: "item",
  },
  legend: {
    orient: "vertical",
    left: "left",
  },
  series: [
    {
      name: "占比",
      type: "pie",
      radius: "50%",
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: "rgba(0, 0, 0, 0.5)",
        },
      },
      data: [], // 这里在使用的时候会被业务数据替换
    },
  ],
};
export { BASEOPTIONS };

pie/index.vue

<template>
  <chart-pie v-bind="$props" />
</template>
<script setup>
import ChartPie from "./chartPie.vue";
</script>

Echart/color.js

// 通用的颜色数组
const COLORSARRAY = ["#f75981", "#90e2a9", "#fe883a", "#2d90d1"];
export {COLORSARRAY};

使用方式
<chartPie :seriesData="dataList" :extraOption="extraOption"></chartPie>


import chartPie from "@/components/Echart/pie/chartPie.vue";
import { ref } from "vue";


const dataList = ref([
  { name: "对接成功", value: 0 },
  { name: "未成功", value: 0 },
]);
const extraOption = {
  color: ["#fe883a", "#2d90d1", "#f75981", "#90e2a9"],
};


// 请求,具体代码省略
if (res.data[0] && res.data[0].data) {
     dataList.value[0].value = res.data[0].data.chenggong_count || 0;
     dataList.value[1].value = res.data[0].data.shenqing_count || 0;
}

最终效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1665284.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2.2、Gitea忘记密码重置密码

忘记密码后&#xff0c;管理员可以使用gitea的主程序输入命令重置密码。 gitea admin user change-password --username myname --password asecurepassword

Python多线程与互斥锁模拟抢购余票的示例

一、示例代码&#xff1a; from threading import Thread from threading import Lock import timen 100 # 共100张票def task():global nmutex.acquire() # 上锁temp ntime.sleep(0.1)n temp - 1print(购票成…

树的基本介绍

引入 定义 表示 相关概念 结点&#xff1a;数据元素与指向分支的指针两部分组成 树的深度&#xff1a;树中结点的最大层次 将树A结点(根结点)去掉&#xff0c;树A就变成了森林 区别 实现

vuex核心概念-actions

目录 一、概述 二、应用场景 三、使用步骤 三、注意 四、辅助函数-mapActions 一、概述 目标&#xff1a;明确actions的基本语法&#xff0c;处理异步操作。 需求&#xff1a;一秒钟之后&#xff0c;修改state的count成666。 说明&#xff1a;mutations必须是同步的(便于…

Softing工业推出的edgeConnector将Allen-Bradley控制器集成到工业边缘应用中

2024年4月17日&#xff08;哈尔&#xff09;&#xff0c;Softing宣布扩展其基于Docker的edgeConnector产品系列&#xff0c;推出了新软件模块edgeConnector Allen Bradley PLC&#xff0c;可方便用户访问来自ControlLogix和CompactLogix控制器数据。 &#xff08;edgeConnector…

【小红书采集工具】根据搜索关键词批量采集小红书笔记,含笔记正文、笔记链接、发布时间、转评赞藏等

一、背景介绍 1.1 爬取目标 熟悉我的小伙伴都了解&#xff0c;我之前开发过2款软件&#xff1a; 【GUI软件】小红书搜索结果批量采集&#xff0c;支持多个关键词同时抓取&#xff01; 【GUI软件】小红书详情数据批量采集&#xff0c;含笔记内容、转评赞藏等&#xff0c;支持…

从诊室到云端:医疗大模型的应用挑战与未来探索

从诊室到云端&#xff1a;医疗大模型的应用挑战与未来探索 2023年是中国医疗大模型发展的元年&#xff0c;各种医疗大模型已广泛应用于临床辅助决策、医学研究、健康管理等多个场景。未来&#xff0c;医疗大模型有望实现多模态AI与医疗实践全流程的深入链接&#xff0c;应用于医…

LibreNMS简介

目录 1 LibreNMS简单介绍1.1 LibreNMS介绍 2 安装2.1 Ubuntu安装1、安装依赖2、添加 librenms 用户3、下载 LibreNMS4、设置权限5、安装 PHP 依赖项6、设置时区7、配置 MariaDB8、配置 PHP-FPM9、配置 Web 服务器10、启用 lnms 命令11、配置 snmpd12、cron13、启用调度程序14、…

OS复习笔记ch5-2

引言 在上一篇笔记中&#xff0c;我们介绍到了进程同步和进程互斥&#xff0c;以及用硬件层面上的三种方法分别实现进程互斥。其实&#xff0c;软件层面上也有四种方法&#xff0c;但是这些方法大部分都存在着一些问题&#xff1a; “上锁”与“检查”是非原子操作&#xff0…

Kafka学习-Java使用Kafka

文章目录 前言一、Kafka1、什么是消息队列offset 2、高性能topicpartition 3、高扩展broker 4、高可用replicas、leader、follower 5、持久化和过期策略6、消费者组7、Zookeeper8、架构图 二、安装Zookeeper三、安装Kafka四、Java中使用Kafka1、引入依赖2、生产者3、消费者4、运…

盛邦安全荣获北京市海淀区上地街道财源建设工作表彰

近日&#xff0c;盛邦安全受邀出席上地街道2024年第一季度财源建设工作联席会暨上地人工智能产业报告发布大会并收到上地街道颁发的感谢信&#xff0c;这是对公司技术创新、管理提升、营收增长&#xff0c;持续为上地地区财源建设做出突出贡献的鼓励。 盛邦安全副总裁、董事会秘…

第四百九十九回

文章目录 1. 概念介绍2. 使用方法2.1 固定样式2.2 自定义样式 3. 示例代码4. 内容总结 我们在上一章回中介绍了"GetMaterialApp组件"相关的内容&#xff0c;本章回中将介绍使用get显示SnackBar.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在介…

pyqt颜色变换动画效果

pyqt颜色变换动画效果 QPropertyAnimation介绍颜色变换效果代码 QPropertyAnimation介绍 QPropertyAnimation 是 PyQt中的一个类&#xff0c;它用于对 Qt 对象的属性进行动画处理。通过使用 QPropertyAnimation&#xff0c;你可以平滑地改变一个对象的属性值&#xff0c;例如窗…

【企业必备】提升企业新质生产力,英智推出私有化大模型定制方案

市面上有很多性能不错的大模型&#xff0c;但大部分企业都不敢使用&#xff0c;担心模型训练和使用过程中出现数据泄露的风险。智能化升级是当今时代企业发展的必然趋势&#xff0c;在大模型发展迅猛的时代&#xff0c;借助AI能力的公司能够更快速提升自身的核心竞争力&#xf…

使用xtuner微调InternLM-Chat-7B

1. 安装xtuner #激活环境 source activate test_llm # 安装xtuner pip install xtuner#还有一些依赖项需要安装 future>0.6.0 cython lxml>3.1.0 cssselect mmengine 2. 创建一个ft-oasst1 数据集的工作路径&#xff0c;进入 mkdir ft-oasst1 cd ft-oasst1 3.XTune…

以Azure为例的SSO

由于文章的篇幅有限&#xff0c;无法将全部的代码贴上来&#xff0c;如想要看完整案例&#xff0c;请在公众号文章中留言(其他平台很少看…毕竟最近印度同事的UI组件库搞得我好烦) 1.关于SSO 单点登录又称之为SSO,全称为 Single Sign On &#xff0c;一般在多个应用系统中&…

LangChain连接国内大模型测试|智谱ai、讯飞星火、通义千问

智谱AI 配置参考 https://python.langchain.com/v0.1/docs/integrations/chat/zhipuai/ZHIPUAI_API_KEY从https://open.bigmodel.cn/获取 from langchain_community.chat_models import ChatZhipuAI from langchain_core.messages import AIMessage, HumanMessage, SystemMes…

【Ubuntu 安装erlang】

apt-get 安装 apt-get install erlang或 源码安装 git clone https://github.com/erlang/otp.git cd otp git checkout maint-25 # current latest stable version ./configure make make install安装完后&#xff0c;验证是否成功 # 命令行输入 erl

漫谈AI时代的手机

以chatGPT 为代表的大语言的横空出世使人们感受到AI 时代的到来&#xff0c;大语言模型技术的最大特点是机器开始”懂人话“&#xff0c;”说人话“了。如同任何一个革命性工具的出现一样&#xff0c;它必将改变人类生活和工作。 在这里。我谈谈AI时代的手机。 语音通信的历史…

【C语言—猜数字小游戏】

一、游戏规则 电脑自动生成一个1~100范围内的随机数&#xff0c;由玩家猜测本轮生成的随机数是什么&#xff0c;系统根据玩家猜测数据的⼤⼩给出猜⼤了或猜⼩了的反馈&#xff0c;直到玩家猜对&#xff0c;游戏结束。 如何生成随机数&#xff1a;【C语言】/*如何生成随机值*/-C…