手摸手带你在vue中封装echarts组件

Posted wiliam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手摸手带你在vue中封装echarts组件相关的知识,希望对你有一定的参考价值。

本文带你在vue中封装echarts折线图,柱状图,饼图等各种组件,实现的思路就是通过props传递参数,使得组件动态渲染

 

首先说一下echarts的安装方式:

1. 通过cdn全局引入:在index.html中引入js代码

<script src="https://cdn.bootcdn.net/ajax/libs/echarts/4.7.0/echarts-en.min.js"></script>,然后通过访问echarts对象就可以。

2.通过npm安装: npm install echarts --save  

然后 var echarts = require(‘echarts‘) 就可以访问echarts对象了;

按需引入及完整引入方式见官网:https://www.echartsjs.com/zh/tutorial.html#%E5%9C%A8%20webpack%20%E4%B8%AD%E4%BD%BF%E7%94%A8%20ECharts

 

接下来以封装官网的Stacked Line Chart (折线图堆叠)为例子:

echarts组件代码:
<template>
  <div :id="testEchartsObj.id" style="width:100%;height:500px;background:#fff;"></div>
</template>
<script>
// 引入基本模板
let $echarts = require("echarts/lib/echarts");
// 引入图形组件
require("echarts/lib/chart/line");
// 引入其他组件
require("echarts/lib/component/title");
require("echarts/lib/component/tooltip");
require("echarts/lib/component/legend");

export default {
  name: "testEcharts",
  props: {
    testEchartsObj: {
      type: Object
    }
  },
  data() {
    return {
      myChart: ""
    };
  },
  methods: {
    initEcharts() {
      this.myChart = $echarts.init(
        document.getElementById(this.testEchartsObj.id)
      );
      this.myChart ? this.myChart.clear() : "";
      var option = {
        //可能你不需要名称,所以名称通过props的self属性动态渲染
        // title: {
        //   text: "折线图堆叠"
        // },
        tooltip: {
          trigger: "axis"
        },
        legend: {
          data: []
        },
        grid: {
          left: "3%",
          right: "4%",
          bottom: "3%",
          containLabel: true
        },
        toolbox: {
          feature: {
            saveAsImage: {}
          }
        },
        xAxis: {
          type: "category",
          boundaryGap: false,
          data: []
        },
        yAxis: {
          type: "value"
        },
        series: []
      };
      this.myChart.setOption(option);
    },
    setEcharts() {
      var _this = this;
      //获取series对象
      var series_data = [];
      _this.nameArr.map((item, index) => {
        var obj = {};
        obj.name = item;
        obj.type = "line";
        obj.stack = "总量";
        obj.data = _this.y_data[index];
        // console.log(obj);
        series_data.push(obj);
      });
      //默认配置
      _this.myChart.setOption({
        xAxis: {
          data: _this.x_data
        },
        legend: {
          data: _this.nameArr
        },
        series: series_data
      });
      //自定义配置
      if (JSON.stringify(_this.self) !== "{}") {
        // console.log(_this.self);
        _this.myChart.setOption(_this.self);
      }
    }
  },
  mounted() {
    this.initEcharts();
    this.setEcharts();
    // console.log(this.x_data, this.y_data, this.nameArr);
    var that = this;
    //监听窗口resize事件
    window.addEventListener("resize", function() {
      that.myChart ? that.myChart.resize() : "";
    });
  },
  //计算属性监听所有props里面的具体属性
  computed: {
    x_data: function() {
      return this.testEchartsObj.x_data;
    },
    y_data: function() {
      return this.testEchartsObj.y_data;
    },
    nameArr: function() {
      return this.testEchartsObj.nameArr;
    },
    self: function() {
      return this.testEchartsObj.self;
    }
  },
  //通过watch整个testEchartsObj使得数据变化后重新渲染echarts图
  watch: {
    testEchartsObj: {
      handler(newValue, oldValue) {
        // console.log(newValue); //props参数
        this.setEcharts();
      },
      deep: true
    }
  }
};
</script>
父组件用法:(里面的数据是固定的,项目中可以通过请求后的,将数据转换成下面的格式,然后传给子组件就行了)
<template>
  <div>
    <test-echarts :testEchartsObj="testEchartsObj"></test-echarts>
    <button @click="testEchartsObj.self.xAxis.axisLabel.interval+=1">增大inter_val</button>
  </div>
</template>

<script>
export default {
  components: {
    testEcharts: () => import("./testEcharts")
  },
  data() {
    return {
      testEchartsObj: {
        id: "test-echarts",
        nameArr: ["邮件营销", "联盟广告", "视频广告", "直接访问", "搜索引擎"],
        x_data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
        y_data: [
          [120, 132, 101, 134, 90, 230, 210],
          [120, 132, 101, 134, 90, 230, 210],
          [150, 232, 201, 154, 190, 330, 410],
          [320, 332, 301, 334, 390, 330, 320],
          [820, 932, 901, 934, 1290, 1330, 1320]
        ],
        //自定义配置
        self: {
          title: {
            text: "自定义名字折线图堆叠"
          },
          xAxis: {
            axisLabel: {
              interval: 0
            }
          }
        }
      }
    };
  }
};
</script>

   ok,现在的话已经完成了一个折线图的封装,上面是使用官网的例子,所以比较简单,但无论什么样的echarts图,都可以按这个思想封装:

  1. 先生成固定数据的echarts图,比如使用Echarts官网提供的option,配置好样式。
  2. 然后把options里面需要动态渲染的数据的值设为空,然后通过父组件的props获取
  3. echarts组件设立两个函数,一个initEcharts函数初始化一些固定配置,如不知是否固定可以不写然后通过self属性获取,另一个是setEcharts函数,通过setOption赋值对应的props
  4. 计算属性用来接收porps的值防止vue报错,然后通过watch监听整个对象,一旦有值发生改变就调用setEcharts函数,重新渲染Echarts图。

 

以上是关于手摸手带你在vue中封装echarts组件的主要内容,如果未能解决你的问题,请参考以下文章

手摸手带你理解Vue的Computed原理

赶紧过来看鸭!鱼头手摸手带你实现一个React!

手摸手带你 Docker 从入门到实践

记录--手摸手带你撸一个拖拽效果

跳坑成功,手摸手带你使用PHP连接Oracle数据库

跳坑成功,手摸手带你使用PHP连接Oracle数据库