likes
comments
collection
share

VUE-Echarts组件封装只在echarts中使用的配置项,占据了大量代码行数,导致代码不够整洁,在修改业务代码时不

作者站长头像
站长
· 阅读数 16

前言

在前端日常工作中,echarts 频繁应用于数据可视化及大屏等功能场景。只在echarts中使用的配置项,占据了大量代码行数,导致代码不够整洁,在修改业务代码时不易于定位到相关问题。重复的图表样式意味着重复的配置项,这也大大增加了代码的冗余度,有时在想使用相同图表时,还需要在掺杂了大量业务代码的echarts配置中抽离自己需要的部分也是极其耗时的,故此封装echarts组件。

介绍

echarts组件分为两部分echarts.vue、echartsOptions.js,其中echarts.vue组件实现了重新绘制echarts、清除echarts、根据分辨率调整echarts、挂载点击事件(也可以后期根据自己的需求增加事件)、echarts数据加载中展示。echartsOptions.js用于保存echarts的配置项,在调用echarts组件时只需要通过name去匹配即可。

组件使用

<XEcharts
    echarts-type="demoOption" 
    echarts-id="demoId"
    ref="demoRef">
</XEcharts>


// data用于传入Echarts的配置项,数据可以根据自己配置的格式自由定义
this.$refs['demoRef'].changeEcharts(data)


属性

属性类型介绍
loadingBoolean用于控制echarts组件的加载中状态
echartsIdString挂载echarts的div id,用于初始化echarts
echartsTypeString对应echartsOptions.js 中的options,用于获取对应的echarts配置
dataObject,Array用于echartsOption配置中的使用的参数,数据格式根据配置项的使用自己定义

事件

事件名返回值介绍
onClickecharts点击事件的返回数据echarts图的点击事件

函数

函数名介绍
changeEcharts重新加载echarts数据
clearEchartsclear echarts图
resizeEcharts调整尺寸
showEchartsLoading更新加载中状态

echarts.vue代码

<template>
  <div style="position: relative;width: 100%;height:100%;">
    <XSpin v-if="showLoading" :></XSpin>
    <div :id="echartsId" :ref="echartsId" style="width: 100%;height:100%;" ></div>
  </div>
</template>

<script>
import {echartsOptions} from "./echartsOptions";
import XSpin from "./XSpin";
export default {
  name: "XEcharts",
  components:{
    XSpin
  },
  props:{
    // 加载中状态
    loading:{
      type: Boolean,
      default: false
    },
    // 挂载echarts的div id
    echartsId:{
      type:String,
      require:true,
      default:()=>{
        return "echartsId"
      }
    },
    // 使用的echarts的配置项
    echartsType:{
      type:String,
      default: ""
    },
    data:{
      type:[Object,Array],
      default: ()=>{
        return {}
      }
    },
  },
  data(){
    return {
      XChart:null,
      chartData:null,
      showLoading:false
    }
  },
  watch:{
    loading:{
      immediate:true,
      handler(val){
        this.showLoading = val
      }
    }
  },
  methods:{
  // 重新加载echarts数据
    changeEcharts(data){
      // 每次重新画图时需要重新清空一下否则在不同分辨率下echarts图大小会有问题
      this.$nextTick(()=>{
        if(this.XChart){
          this.XChart.clear();
          this.XChart.resize();
          this.XChart.setOption(echartsOptions.getOption(this.echartsType,data));
          this.chartData = data
        }
      })
    },
    // clear echarts图
    clearEcharts(){
      if(this.XChart){
        this.XChart.clear();
      }
    },
    // 调整尺寸
    resizeEcharts(){
      if(this.XChart){
         // 防止在页面拖动时过于频繁的重新绘制
        setTimeout(()=>{
          this.XChart.setOption(echartsOptions.getOption(this.echartsType,this.chartData));
          this.XChart.resize();
        },300)
      }
    },
    // 更新加载中状态
    showEchartsLoading(param){
      this.showLoading = param
    },
  },
  mounted() {
  // 初始化echarts,并添加事件
    this.$nextTick(()=>{
      this.XChart = this.$echarts.init(document.getElementById(this.echartsId));
      this.XChart.off('click')
      this.XChart.on('click',(param=>{
        this.$emit("onClick",param)
      }))
    })
    let that = this
    // 当窗口大小发生变化时调整echarts尺寸
    window.addEventListener('resize', function(event) {
      that.resizeEcharts();
    });
  },
}
</script>

<style scoped>

</style>

echartsOptions.js

options 用于配置echarts的配置项

import * as echarts from "echarts";
const options = {
// 配置示例,categoryPie对应vue组件中echartsType的值
categoryPie: (data) => {
  return {
    tooltip: {
      trigger: "item",
      formatter: "{b} : {c} 条",
    },
    legend: {
      type: "scroll",
      orient: "vertical",
      textStyle: {
        color: "#FFFFFF",
      },
      width: '5%',
      right: 'right',
      formatter: function (name) {
        for (let i in data) {
          if (data[i].name === name) {
            return `${name}${data[i].value}条`.replace(/\s%/g, "");
          }
        }
        return '';
      },
    },
    series: [
      {
        type: "pie",
        radius: ["35%", "65%"],
        center: ["30%", "50%"], //饼图位置
        label: {
          show: false,
          position: "center",
        },
        emphasis: {
          label: {
            show: false,
            fontSize: 21,
            fontWeight: "bold",
          },
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: "#7AADFF",
          },
        },
        data: data,
      },
    ],
  };
},
}

export const echartsOptions = {
  getOption: (type, data) => {
    try {
      if (type && data) {
        return options[type](data);
      }
    } catch (e) {
      console.log(e);
    }
    return {};
  },
};
转载自:https://juejin.cn/post/7423235291265318946
评论
请登录