vue封装echarts并实现大小动态自适应变化---超有用哇

Posted 北极光之夜。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue封装echarts并实现大小动态自适应变化---超有用哇相关的知识,希望对你有一定的参考价值。

一.先看效果:

大家好呀,⭐⭐⭐⭐⭐,秉着分享快乐的原则,我又来啦~

echarts不就是去官网复制然后粘贴吗,为什么要封装?

1.减少代码量,每次只要传宽度,高度与option配置项便能快速生成图表。
2.原先的echarts并不能自适应屏幕大小变化。
3.原先的echarts并不能自适应父盒子大小变化。

原先自适应存在问题(重):

1.当屏幕改变,图表不会重新动态改变并渲染:

2.当图表标签的父盒子大小改变时,图表不会重新动态改变并渲染:

3.当屏幕改变,图表不会重新动态改变并渲染 (解决后)


4. 当图表标签的父盒子大小改变时,图表不会重新动态改变并渲染 (解决后)

二.详细实现:

1. 组件要传的值:

先分析需求,比如组件名字为my-echarts,一般传个width(宽)、height(高)、option(配置项)这三个就可以了,如:

  <my-echarts
        :width="'80%'"
        :height="'20vw'"
        :option="option1"
  ></my-echarts>

2. 实现组件代码:

在一个vue脚手架工程里,可以在components目录下新建一个 MyEcharts.vue 文件,具体功能代码看注释

<template>
  <!-- 定义标签 -->
  <div
    :id="id"
    :style="
      width: width,
      height: height,
    "
  ></div>
</template>

<script>
import * as echarts from "echarts";
// 2.生成一个 id 值给标签,目的是为了当多次使用组件防止id重复
const uid = function () 
  return new Date().getTime();
;
export default 
  //1.获取传过来的值
  props: 
    width: 
      typeof: String,
    ,
    height: 
      typeof: String,
    ,
    option: 
      typeof: Object,
      default() 
        return null;
      ,
    ,
  ,
  data() 
    return 
      //3.在这定义 id 与 myChart图表实例 , 方便管理
      id: null,
      myChart: null,
    ;
  ,
  created() 
    // 4.id赋值
    this.id = uid();
  ,
  mounted() 
    //   5. 创建echarts图表实例
    this.myChart = echarts.init(document.getElementById(this.id));
    // 指定图表的配置项和数据
    var option = this.option;
    // 使用刚指定的配置项和数据显示图表。
    this.myChart.setOption(option);
  ,
;
</script>

3. 基本使用:

此时便可以在其它地方使用my-echarts组件,比如我在 App.vue使用该组件:

导入:

import MyEcharts from "./components/MyEcharts.vue";

注册:

 components: 
    MyEcharts,
  ,

定义option数据,(可以随便去echarts官网复制一个):

data() 
    return 
      //三角形柱状图
      option1: 
        tooltip: 
          trigger: "axis",
          formatter: `b<br/>
                a: c 千人`,
        ,
        //图表的内边距
        grid: 
          left: "3%",
          top: "20%",
          right: "3%",
          bottom: "1%",
          show: true,
          borderColor: "rgb(47,32,71)",
          containLabel: true,
        ,
        xAxis: 
          data: ["衬衫", "羊毛衫", "雪纺衫", "裤子"],
          type: "category",
          axisLabel: 
            show: true,
            color: "rgb(142,175,220)",
          ,
          axisTick: 
            //不显示刻度线
            show: false,
          ,
          axisLine: 
            show: true,
            lineStyle: 
              width: 1,
              color: "rgba(47,32,71)",
            ,
          ,
          // 区域分割线
          splitLine: 
            show: false,
            lineStyle: 
              color: "rgba(204, 204, 204,0.3)",
            ,
          ,
        ,
        yAxis: 
          name: "单位:千人",
          nameTextStyle: 
            color: "rgb(142,175,220)",
          ,
          // 区域分割线
          splitLine: 
            lineStyle: 
              color: "rgba(47,32,71)",
            ,
          ,
          axisTick: 
            show: false,
          ,
          axisLabel: 
            show: true,
            color: "rgb(142,175,220)",
          ,
          axisLine: 
            lineStyle: 
              show: true, //是否显示坐标轴轴线,
              color: "white", //y轴轴线的颜色
              width: 0.5, //x轴粗细
            ,
          ,
        ,
        series: [
          
            name: "销量",
            //三角形柱状图
            type: "pictorialBar",
            barCategoryGap: "30",
            symbol:
              "path://M0,10 L10,10 C5.5,10 5.5,5 5,0 C4.5,5 4.5,10 0,10 z",
            //渐变色
            itemStyle: 
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                 offset: 0, color: "#188df0" ,
                 offset: 0.5, color: "#188df0" ,
                 offset: 1, color: "#83bff6" ,
              ]),
            ,
            data: [5, 20, 36, 10],
          ,
        ],
      ,
    ;
  ,

定义标签:

      <my-echarts
        :width="'80%'"
        :height="'20vw'"
        :option="option1"
      ></my-echarts>

4. 当屏幕改变,图表重新动态改变并渲染(重点):

echarts自带一个resize()方法能重新渲染绘制图表,但是要手动调用它,那么我们用window.onresize事件方法,当屏幕大小改变就调用echarts的resize()方法。

在 MyEcharts.vue 组件文件里添加:

。。。略
 mounted() 
    // 当屏幕改变,图表重新动态改变并渲染
    var that = this;
    window.onresize = function () 
      that.myChart.resize();
    ;
  ,
  。。。略

此时便可以:

5. 当图表标签的父盒子大小改变时,图表重新渲染(重):

这个方法我们新建一个mixin.js文件写,随意地方建,到时导入路径写对就行,然后在MyEcharts.vue里通过混入mixin.js文件,能更方便复用,代码实现详细看注释:

// echarts 自适应父盒子变化大小
const myMixin = 
  methods: 
    resize() 
      // 当宽高变化时就会执行
      //执行某些操作 重新改变图表, 同时传参,设置动画效果
      this.myChart.resize(animation: duration:1000);
    ,
  ,
    //自定义指令,图表的宽度采用百分比,父盒子宽度变化,那图表盒子大小也变化了,但是图表不会重新绘制
  //原理:判断盒子本身宽度改变了,再调用echarts的resize方法重新绘制
  directives: 
    // 使用局部注册指令的方式
    resize: 
      // 指令的名称
      bind(el, binding) 
        // el为绑定的元素,binding为绑定给指令的对象
        let width = "",
          height = "";
        function isReize() 
          //这个方法可以获取元素的css样式对象
          const style = document.defaultView.getComputedStyle(el);
          //对比跟上次宽度是否改变,如果改变了
          if (width !== style.width || height !== style.height) 
            //调用resize方法
            binding.value(); // 关键
          
          //记录当前宽高
          width = style.width;
          height = style.height;
        
        //设置监听器,每隔一段时间对比看看
        el.__vueSetInterval__ = setInterval(isReize, 300);
      ,
      //只调用一次,指令与元素解绑时调用
      unbind(el) 
        //清除定时器
        clearInterval(el.__vueSetInterval__);
      ,
    ,
  ,


export myMixin;

在MyEcharts.vue 混入:

先定义自定义指令:

 <div
    v-resize="resize"
    :id="id"
    :style="
      width: width,
      height: height,
    "
  ></div>

然后在混入mixin.js:

import  myMixin  from "../assets/mixins/mixin.js";

export default 
  mixins: [myMixin],
//.....略

此时便实现如下:

6. 题外话:

第五步,说到底,是监听dom元素变化,我用的是定时器每隔一段时间监听一次,其实并不好,浪费性能。而 ResizeObserver API 这个新特性就可以帮助我们监听一个DOM节点的变化。但是这是一个实验中的功能,有兴趣可以自行查阅看看。我也可以专门出一篇文章,需要的话,哈哈~

三.总结:

上面就是全部功能实现啦,是比较简单的,有不明白的可以评论区留言呀~😆😆😆

下次见,拜拜~ ┏(^0^)┛

推荐一部电影给你们- - -小森林(超治愈~)

我的哔哩哔哩空间
Gitee仓库地址:全部特效源码
Q群聊(欢迎):629596039
其它文章:
~关注我看更多简单创意特效:
文字烟雾效果 html+css+js
环绕倒影加载特效 html+css
气泡浮动背景特效 html+css
简约时钟特效 html+css+js
赛博朋克风格按钮 html+css
仿网易云官网轮播图 html+css+js
水波加载动画 html+css
导航栏滚动渐变效果 html+css+js
书本翻页 html+css
3D立体相册 html+css
霓虹灯绘画板效果 html+css+js
记一些css属性总结(一)
Sass总结笔记
…等等
进我主页看更多~

以上是关于vue封装echarts并实现大小动态自适应变化---超有用哇的主要内容,如果未能解决你的问题,请参考以下文章

vue封装echarts并实现大小动态自适应变化---超有用哇

echarts图表初始大小问题及echarts随窗口变化自适应

Vue封装echarts组件

echarts自适应

容器改变/窗口改变重新渲染echarts

echarts生成的图表大小怎么随屏幕的大小改变自适应