在vue项目中封装echarts的正确姿势

为什么需要封装echarts

  • 每个开发者在制作图表时都需要从头到尾书写一遍完整的option配置,十分冗余
  • 在同一个项目中,各类图表设计十分相似,甚至是相同,没必要一直做重复工作
  • 可能有一些开发者忘记考虑echarts更新数据的特性,以及窗口缩放时的适应问题。这样导致数据更新了echarts视图却没有更新,窗口缩放引起echarts图形变形问题

我希望这个echarts组件能设计成什么样

  • 业务数据和样式配置数据分离,我只需要传入业务数据就行了
  • 它的大小要完全由使用者决定
  • 不会因为缩放出现变形问题,而是能很好地自适应
  • 有时候某个图表的样式可能有点不一样,希望能保留自己配置样式的灵活性
  • 无论传入什么数据都能正确地更新视图
  • 如果我传入的数据为空,能展示一个空状态

公共组件结构建议

  • 当你把它书写为一个公共组件时,我我希望它应该是这样:将单独机械的配置表独立成一份文件,暴露一个必要的vue单文件,同时携带一份README说明文档,当然,文档里面需要有关于你写的组件的使用示例和入参含义说明,这在大型项目中非常重要。

vue单文件代码

  • 完整代码如下:
<template>  <div class="chart"></div></template>

<script>import { merge, isEmpty } from "lodash";import echart from "echarts";import { BASIC_OPTION, EMPTY_OPTION } from "./default_option";

export default {  props: {    // 业务数据    dataList: {      type: Array,      default: () => []    },    // 特殊的样式定制    extraOption: {      type: Object,      default: () => ({})    }  },  data() {    return {      chart: null    };  },  methods: {    /**     * 将业务数据加入到基础样式配置中     * @returns {Object} 完整的echart配置     */    assembleDataToOption() {      return merge(        {},        BASIC_OPTION,        {          series: [{ data: this.dataList }]        },        this.extraOption      );    },

    /**     * 更新echart视图     */    updateChartView() {      if (!this.chart) return;

      const fullOption = isEmpty(this.dataList)        ? EMPTY_OPTION        : this.assembleDataToOption();      this.chart.setOption(fullOption, true);    },

    /**     * 当窗口缩放时,echart动态调整自身大小     */    handleWindowResize() {      if (!this.chart) return;      this.chart.resize();    }  },  watch: {    dataList: {      deep: true,      handler: () => this.updateChartView    }  },  mounted() {    this.chart = echart.init(this.$el);    this.updateChartView();    window.addEventListener("resize", this.handleWindowResize);  },  beforeDestroy() {    window.removeEventListener("resize", this.handleWindowResize);  }};</script>

<style lang="less" scoped>.chart {  width: 100%;  height: 100%;}</style>

关于源码的说明

  • 在源码中,我用到了lodash的一个公共函数merge,它表示递归合并来源对象自身和继承的可枚举属性到目标对象。后续的来源对象属性会覆盖之前同名的属性
  • 另外一个有幸被我宠幸的函数是isEmpty,当我传入的业务数据为空时,比如空数组[]undefinednull时,都会被认为这是一个无数据的情况,这时候我们就选用一个空状态的echarts配置,即EMPTY_OPTION
  • 在绑定到具体的DOM元素时,我没有用querySelector选择器去选择一个类或者是用Math.random生成的id,因为这两者都不是绝对可靠的,我直接使用当前vue示例关联的根DOM 元素$el
  • 我监听窗口大小的变化,并为这种情况添加对应的事件处理函数--echarts自带的resize方法,使echarts图形不会变形
  • 将对应DOM的宽高设为100%,让其大小完全由使用者提供的容器控制
  • setOption方法的第二个参数表示传入的新option是否不与之前的旧option进行合并,默认居然是false,即合并。这显然不行,我们需要每次的业务配置都是完全独立的
  • 命名非常语义化,一看就懂
  • 保留了自己需要单独配置一些定制样式的灵活性,即extraOption
  • 关于dataList和extraOption的具体含义,使用示例,都放在README.md文件做详细说明,使用者一看文档就能上手

default_option.js应该包括哪些内容

  • 应该包括两部分:正常情况下的基础配置BASIC_OPTION,异常情况下(数据为空)的EMPTY_OPTION,如下:

组件使用示例

<template>  <div class="echart-wrapper">    <chart-pie :data-list="pieData" :extra-option="option" />  </div></template>

<script>import ChartPie from "@/components/echarts/echart_pie/EchartPie.vue";

export default {  name: "home",  data() {    return {      // 业务数据      pieData: [        {          name: "西瓜",          value: 20        },        {          name: "橘子",          value: 13        },        {          name: "杨桃",          value: 33        }      ],      // 定制化配置覆盖默认配置      option: {        color: ["#e033f7", "#15c28e", "#2267e6"]      }    };  },  components: {    ChartPie  }};</script>

<style lang="less" scoped>.echart-wrapper {  width: 300px;  height: 300px;  margin: 10px auto;}</style>

效果图

  • 当数据正常时,效果如下
  • 当无数据时,效果如下

可以更进一步优化的地方

  • 我这一手封装已经是上乘之作,如果一定说哪里不足的话,我认为在resize的节流方面可以考虑引入lodash中的throttle节流函数,进一步优化性能。

原文地址:https://www.cnblogs.com/zhangnan35/p/12680038.html

时间: 2024-08-16 22:59:20

在vue项目中封装echarts的正确姿势的相关文章

Vue系列——在vue项目中使用echarts

安装echarts依赖 npm install echarts -S 创建图表 全局引入 main.js // 引入echarts import echarts from 'echarts' Vue.prototype.$echarts = echarts Hello.vue <div id="myChart" :style="{width: '300px', height: '300px'}"></div> export default {

如何在vue项目中使用echarts和高德地图绘制折线和热力图

1.先下载相关的依赖,这里echarts和高德地图放到一起.(高德地图需要先去申请一个key) // The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router fr

vue项目常用方法封装,持续更新中。。。

vue项目中可以直接使用 1.常用工具类untils.js中 /* * 验证手机号是否合格 * true--说明合格 */ export function isPhone(phoneStr){ let myreg = /^[1][3,4,5,7,8,9][0-9]{9}$/; if (!myreg.test(phoneStr)) { return false; } else { return true; } } /* * 验证身份证号是否合格 * true--说明合格 */ export fun

如何在Vue项目中给路由跳转加上进度条

1.前言 在平常浏览网页时,我们会注意到在有的网站中,当点击页面中的链接进行路由跳转时,页面顶部会有一个进度条,用来标示页面跳转的进度(如下图所示).虽然实际用处不大,但是对用户来说,有个进度条会大大减轻用户的等待压力,提升用户体验.本篇文章就来教你如何在Vue项目中实现这样的进度条. 2.安装Nprogress 虽然我们也可以自己手动实现这样的功能,但是,nprogress.js已经帮我们把进度条的样式呀,功能呀都已经封装的很好了,既然有现成的轮子,我们就直接使用轮子就好啦! npm inst

vue 项目中当访问路由不存在的时候默认访问404页面

前言: 在Vue项目中,当访问的页面路由不存在或错误时,页面显示为一片空白.然而,通常我们需要对访问url不存在或者错误的情况下添加默认的404页面,即not found页面. 一般的处理方法是: 在最后添加一个path: * ,优先级从上到下查找路由,都没有的时候全部指向 404页面 ,代码如下: const baseRoute = [ { path: '/login', name: 'login', component: Login }, {path: '/', redirect: '/in

解决vue项目中引入组件时出现的Module is not installed问题

如图,在vue项目中import自己定义的组件时,‘@api/table’出现下划线,ctrl+右键点击不会跳转到对应组件.鼠标移上去显示Module is not installed,多方查询后终于弄清楚了原因. 图中路径中有个@符号,这个符号是在build目录下的webpack.base.conf.js文件中定义的,代表当前项目的src目录. 之所以出现上述问题是因为在下图中的webpack中没有指定webpack 的配置文件,或者配置文件指定得不对.找到原因后解决方案就简单了,只需要将该配

Vue 项目中使用 jsPlumb

jsPlumb 介绍 jsPlumb 是一个强大的 JavaScript 连线库,它可以将 html中 的元素用箭头.曲线.直线等连接起来,适用于开发 Web 上的图表.建模工具.流程图.关系图等. jsPlumb 参考网站 博客园:http://www.cnblogs.com/leomYili/p/6346526.html?utm_source=itdadao&utm_medium=referral 官网:https://www.jsplumbtoolkit.com/ 安装 jsPlumb v

vue项目中使用阿里iconfont图标

在上一篇文章中介绍了如何在vue项目中使用vue-awesome,如果你想了解,请移步<vue项目中使用vue-awesome> 这里介绍一下vue项目中如何使用阿里的iconfont图标库,先看一下官网 可以看到有将近两百万的图标量,可以说我们想要的矢量图图标这里大部分都是有的,下面直接开始如何在vue项目中使用,方法有两种 方法一:简单粗暴法 1.打开 iconFont官网 选择自己喜欢的图标,并且添加购物车 例如我现在选择三个图标 点击购物车,添加至项目 为了方便可以给项目起一个名字 选

如何在Vue项目中使用vw实现移动端适配

https://www.w3cplus.com/mobile/vw-layout-in-vue.html  原文网址 如何在Vue项目中使用vw实现移动端适配 作者:大漠 日期:2018-01-25 点击:10362 vw Layout 布局 Vue mobile 编辑推荐:使用 Coding.net 搭建静态博客,自定义域名,全站 HTTPS 加密,自动实时部署, 立即托管您的网站! 有关于移动端的适配布局一直以来都是众说纷纭,对应的解决方案也是有很多种.在<使用Flexible实现手淘H5页