在Vue中使用echarts的实例代码(3种图)

发布时间 - 2026-01-11 02:16:17    点击率:

前言

公司的项目中需要对数据做可视化处理,高级点的D3.js目前还没接触到,因此选用了大众化的Echarts, 在vue的生态系统中已经有实现好的vue-echarts,但是使用现成的就意味着必须使用它定制好的数据结构,我也没办法对他进行一些修改。我个人也偏向于原生JS编程,因此没有采用,而是自己在vue中实现了对数据的可视化处理,先来看看效果图

以下数据已做脱敏处理



这是目前用到的三种图。

可以看到,我在图表的外部添加了标题及说明,以及右侧的选择框组件,视图可以根据选择的不同,图表进行动态切换(echarts也是数据驱动),这就是个人定制化的好处

总体数据流向

所有的数据都是动态获取的,由前端向后台请求。当然请求数据肯定不会放在图表组件中,而是放在了外部。因为架构设计的不合理(MD前端就我一个人!),因此前期获取数据及存取数据的方式,和后期也较大的不同。

1. 存放在vuex中

这么大型的项目,vuex少不了。在前面的组件中,一次请求数据,然后将数据存储到了vuex中,echarts组件再从vuex中获取数据。这样的做法可能代码要稍微复杂点,但是数据存储在vuex中是随时可见的,我们也能随时保存获取的结果,对这些数据可以添加收藏也可以加入缓存中,下次再请求可以先从缓存调用。
(然而这只是我前端的想法,后台已经实现了对请求数据的缓存)

2. 存放在组件中,再分派到echarts组件

再对数据进行还原的时候(我的收藏,最近浏览),因为不需要保存或者收藏数据,我就直接用一个父组件请求,然后再分发到echarts组件,这样没有经过vuex,代码想多要少些。

组件代码

<template>
 <div class="r-echarts-line">
  <div class="top">
   <div class="title">
    {{origin.title}}
   </div>
   <div class="select-list">
    <Select style="width:120px;margin-right:.5rem" v-model="pagePick">
     <Option v-for="item in origin.page_select" :key="item" :value="item.val">{{item.name}}</Option>
    </Select>
    <Select style="width:120px" v-model="typePick">
     <Option v-for="item in typeList" :value="item.name" :key="item">{{item.name}}</Option>
    </Select>
   </div>
  </div>
  <div class="des">说明:符合于本次筛选条件的共有<span class='tips'>{{origin.desc}}</span>条<span style="font-weight:700;color:black">职位信息</span>。</div>
  <div class="bottom" id="echart" ref="mychart">

  </div>
 </div>
</template>

这是组件的html部分,可以看见top以及des是我自己添加的,bottom才是核心,也是整个echarts展示的部分,注意这里添加了ref,在script的代码中,我们将通过这个钩子,将DOM挂载到echarts中

<script>
// echarts相关
let echarts = require('echarts/lib/echarts');
require('echarts/lib/chart/bar');
require('echarts/lib/component/tooltip');
require('echarts/lib/component/toolbox');
require('echarts/lib/component/legend');
require('echarts/lib/component/markLine');

export default {
 name: 'r-echarts-line',
 data () {
  return {
  typePick: '数值',
  typeList: [
   {
    name: '数值'
   },
   {
    name: '百分比'
   }
  ],
  pagePick: 0,
  // myChart实例
   myChart: {},
   percent: {
    label: {
     normal: {
      show: true,
      position: 'inside',
      formatter: '{c}%'
     }
    }
   },
   numeric: {
    label: {
     normal: {
      show: true,
      position: 'inside',
      formatter: '{c}'
     }
    }
   }
  }
 },
 props: {
  index: {
   required: true,
   type: Number
  },
  data: {
   required: true,
   type: Object
  }
 },
 mounted () {
  this.setEchart();
 },
 updated () {
  if (!this.myChart) {
   this.setEchart();
  }
  this.chartChange();
 },
 computed: {
  origin () {
   return this.data;
  },
  opt() {
   let that = this;
   let obj = {
    color: ['#606c94'],
    tooltip: {
    },
    toolbox: {
      show: true,
      feature: {
        saveAsImage: {show: true}
      }
    },
    label: {
     normal: {
      show: true,
      position: 'inside',
      formatter: '{c}'
     },
     emphasis: {
      show: true
     }
    },
    xAxis: {
     type: 'value',
    },
    yAxis: {
     data: that.origin[that.type][that.pagePick].key,
     axisLabel: {
      interval: 0,
      rotate: -30
     }
    },
    series: [{
     name: that.origin.title,
     type: 'bar',
     data: that.origin[that.type][that.pagePick].val,
     barMaxWidth: '30',
     markLine: {
      data: [
       {type: 'average', name: '平均值'}
      ]
     }
    }]
   }
   return obj;
  },
  type () {
   if (this.typePick == '数值') {
    return 'numeric';
   } else if (this.typePick == '百分比') {
    return 'percent';
   } else {
    return 'numeric';
   }
  }
 },
 methods: {
  setEchart () {
   let dom = this.$refs.mychart;
   this.myChart = echarts.init(dom);
   this.myChart.setOption(this.opt);
  },
  chartChange () {
   this.myChart.setOption(this.opt);
   if (this.typePick == '百分比') {
    this.myChart.setOption(this.percent);
   }
   if (this.typePick == '数值') {
    this.myChart.setOption(this.numeric);
   }
  }
 }
}
</script>

首先我引入了需要的echarts组件,这个部分通过npm i echarts -S添加。

接着data部分我设置了那些将会引起变化的参数。需要注意的是,我并没有将echarts的opt部分写入到data中,因为整个图表是基于数据驱动的,并且随时会发生变化,因此我将opt设置为计算属性computed,这样opt将会根据我的选择动态变化,echarts也将动态响应,mychart用于接收echarts生成的图表实例,再参数变换的时候将会起作用。

props部分是我接收到的参数,这个组件时基于前面我讲的第二种方式——父组件获取数据分发,data是父组件分发给echarts的数据源。

暂时忽略两个Vue生命周期钩子, 后面讲

计算属性中设置了两个属性,origin和opt,注意这个origin很重要,通过它我将opt项与复杂的数据解耦,无论外面的数据怎么换,opt只关心origin的值,而这个opt在两种数据获取的方式中是不一样的,使用vuex的方式,origin将会直接从vuex中获取数据。这样一定程度上也实现了组件的复用。

opt就是该图表组件的设置项了,这个参数按照官网给的配置,自己搭配即可。

接下来是methods部分,setEchart将会完成对整个图表的初始化,通过this.$refs获取DOM实例,再由echars生成实例并绑定在data中的mychart选项。

chartChange是用来响应我自定义组件的变化的,针对选框的不同将会有不同的显示情况。在这里是百分比和数据的切换

接着是前面忽略的生命周期部分

mounted里使用setEchart方法,初始化图表组件,一定要在这里使用该方法,否则会找不到DOM

updated周期里是响应参数变化的方法,首先检测该实例有没有生成(单页应用因为用户可能存在的误操作,很可能导致实例没有生成,这里检测是很有必要的),接着在vue中的数据发生改变时运行chartChange方法,注意,我的选择框是没有绑定事件的,只是通过v-model改变了参数,然后opt动态响应了参数的变化。当opt的参数变化的时候,updated中的方法就会执行,echarts也会动态响应。这个就是使用基于数据驱动vue最精巧的地方,避免了通过事件调用echartChange方法。也是vue中使用echarts核心的一环

另外还有一个就是获取地图参数的,并不用在官网里下载,提供的npm包里就有,按需引用就好了(使用官网的js版本会报错没找到echarts)

import echarts from 'echarts/lib/echarts';
import 'echarts/lib/chart/map';
import 'echarts/map/js/china.js';

style部分就没什么好聊的了,只需要记住一点,必须显式指定加载echarts 的DOM的宽度和高度

父组件对echarts组件的调用

调用组件的方法按照常规组件调用就好了,只是因为echarts加载数据绘制需要耗费不少时间,我们可能需要通过keep-alive保存组件在内存中,避免切出去的时候被释放了。另外可能一个页面需要展示多个echarts类型组件,这里考虑使用component动态组件

<template>
 <div class="focus-echarts-wrap">
  <keep-alive>
   <component :is="currentView" :index="focusType"></component>
  </keep-alive>
 </div>
</template>

其他问题

在生成柱状图和饼状图的时候,加载时间并不算太慢。只是在加载地图类型的时候,尤其是我在生成中国地图的时候,达到了10s+的延迟,并且阻塞的是主线程,这段时间用户是无法操作的,相当于卡顿的情况。

该数据是在32bit的QQ浏览器上测得的,同事用的64bit的谷歌浏览器会好一点。

初步判断是echarts的问题。当然也因为是在dev模式下,可能和我打开了vuex和事件的监测有关。具体的延迟时间我会在线上版本测试,希望情况会好转吧。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# vue使用echarts  # vue  # echarts  # 使用地图  # vue.js使用echarts  # 在vue中添加Echarts图表的基本使用教程  # vue使用echarts图表的详细方法  # 详解vue使用Echarts画柱状图  # vue使用echarts图表自适应的几种解决方案  # Vue中使用ECharts与v-if的问题和解决方案  # 将会  # 放在  # 的是  # 这是  # 加载  # 是在  # 在这里  # 我在  # 官网  # 实现了  # 我将  # 绑定  # 都是  # 数据存储  # 就好了  # 我就  # 就会  # 会有  # 还没  # 也会 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置  Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境  Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案  WordPress 子目录安装中正确处理脚本路径的完整指南  node.js报错:Cannot find module &#39;ejs&#39;的解决办法  html文件怎么打开证书错误_https协议的html打开提示不安全【指南】  CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】  网站建设保证美观性,需要考虑的几点问题!  Laravel怎么连接多个数据库_Laravel多数据库连接配置  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  如何挑选优质建站一级代理提升网站排名?  Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程  如何在云虚拟主机上快速搭建个人网站?  敲碗10年!Mac系列传将迎来「触控与联网」双革新  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  教你用AI润色文章,让你的文字表达更专业  Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  EditPlus中的正则表达式实战(6)  Laravel如何使用Gate和Policy进行授权?(权限控制)  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  iOS中将个别页面强制横屏其他页面竖屏  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  教你用AI将一段旋律扩展成一首完整的曲子  C++用Dijkstra(迪杰斯特拉)算法求最短路径  linux top下的 minerd 木马清除方法  香港服务器网站推广:SEO优化与外贸独立站搭建策略  Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明  Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲  JavaScript数据类型有哪些_如何准确判断一个变量的类型  Laravel如何保护应用免受CSRF攻击?(原理和示例)  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  南京网站制作费用,南京远驱官方网站?  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  高防服务器租用指南:配置选择与快速部署攻略  Laravel Asset编译怎么配置_Laravel Vite前端构建工具使用  如何注册花生壳免费域名并搭建个人网站?  如何在Windows虚拟主机上快速搭建网站?  Laravel如何使用Livewire构建动态组件?(入门代码)  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  北京的网站制作公司有哪些,哪个视频网站最好?  如何生成腾讯云建站专用兑换码?  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  如何快速生成ASP一键建站模板并优化安全性?  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  高性能网站服务器配置指南:安全稳定与高效建站核心方案  详解MySQL数据库的安装与密码配置  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  制作旅游网站html,怎样注册旅游网站?