前言

       在做数据可视化大屏页面展示时,或多或少都会用到echarts去歇一歇图表,比如饼图、柱状图、折线图等等,但是如果所有的图表代码都在vue页面中去写会造成代码冗余,同时也不便于后期拓展,所以我们要将这部分代码给写到外面,将他们进行封装。

要将 Echarts 封装成 Vue 组件,可以使用以下步骤:

1. 首先,在 Vue 项目中安装 Echarts 库。可以通过 npm 安装:

npm install echarts --save

2. 创建一个 Vue 组件,为了方便起见,我们可以把 Echarts 的图表和配置项作为组件的 props:

<template>
  <div class="chart"  ref="chart" :style="{ width: '100%', height: '400px' }"></div>
</template>
 
<script>
export default {
  name: "Chart",
  data() {
    return {
      chart: null,
    };
  },
  props: {
    // 传配置项option
    option: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  watch: {
    option() {
      if (this.chart) {
          this.chart.setOption(this.option); // 设置对应配置项
      }
    }
  },
  mounted() {
    this.chart = this.$echarts.init(this.$refs.chart); // 初始化echarts
    this.chart.setOption(this.option); // 设置对应配置项
    // 当窗口大小改变 echarts重置大小
    window.addEventListener("resize", () => {
      this.chart.resize();
    });
  },
};
</script>
或者采用第二种方式封装组件,第二种方式比较推荐
  <template>
    <div :class="className" :style="{height:height,width:width}" />
  </template>
  
  <script>
    import * as echarts from 'echarts'
  require('echarts/theme/macarons') // echarts theme
  import resize from '../../dashboard/mixins/resize'
  
  export default {
    mixins: [resize],
    props: {
      className: {
        type: String,
        default: 'chart'
      },
      width: {
        type: String,
        default: '100%'
      },
      height: {
        type: String,
        default: '100px'
      },
      autoResize: {
        type: Boolean,
        default: true
      },
    //   chartData: {
    //     type: Object,
    //     required: true
    //   }
    },
    data() {
      return {
        chart: null
      }
    },
    mounted() {
      this.$nextTick(() => {
        this.initChart()
      })
    },
    beforeDestroy() {
      if (!this.chart) {
        return
      }
      this.chart.dispose()
      this.chart = null
    },
    methods: {
      initChart() {
        this.chart = echarts.init(this.$el, 'macarons')
        this.setOptions()
      },
      setOptions() {
        this.chart.setOption(...传入的配置项参数)
      }
    }
  }
  </script>

------
// 传配置项option
        option: {
            type: Object,
            default() {
                return {};
            },
        },

watch: {
    option() {
      if (this.chart) {
          this.chart.setOption(this.option); // 设置对应配置项
      }
    }
  },

3. 在父组件中使用新创建的 Echarts 组件

<template>
  <div>
    <chart class="chart" :option="earningOption" />
  </div>
</template>
<script>
import Chart from "../echarts/chart.vue";
 
export default {
  components: {
    Chart,
  },
  data() {
    return {
      earningOption: {
        // 在这里放置 Echarts 的配置项
      },
    };
  },

这样,我们就可以在 Vue 中使用 Echarts 图表了。当父组件渲染时,会传递配置项到子组件中,然后子组件会创建一个 Echarts 实例并渲染图表。

举例说明:

如果要实现如下这种情况的双环饼图并且需要创建6个,难道兄弟们还要写6遍吗?no no no,接下来,看我操作。

 将组件封装,传参为饼图颜色

封装组件代码
--pieCharts.vue
<template>
    <div :class="className" :style="{ height: height, width: width }" />
</template>
  
<script>
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from '../../dashboard/mixins/resize'

export default {
    mixins: [resize],
    props: {
        className: {
            type: String,
            default: 'chart'
        },
        width: {
            type: String,
            default: '100%'
        },
        height: {
            type: String,
            default: '100px'
        },
        autoResize: {
            type: Boolean,
            default: true
        },
        color: {
            type: String,
            default: '#fff'
        },
    },
    data() {
        return {
            chart: null
        }
    },
    watch: {
        option() {
            if (this.chart) {
                this.chart.setOption(); // 设置对应配置项
            }
        }
    },
    mounted() {
        this.$nextTick(() => {
            this.initChart()
        })
    },
    beforeDestroy() {
        if (!this.chart) {
            return
        }
        this.chart.dispose()
        this.chart = null
    },
    methods: {
        initChart() {
            this.chart = echarts.init(this.$el, 'macarons')
            this.setOptions()
        },
        setOptions() {
            this.chart.setOption({
                title: {
                    // 设置饼图标题,位置设为顶部居中
                    text: "Ld",
                    top: "-4%",
                    left: "10%",

                },
                series: [
                    {
                        name: 'Ln1',
                        type: 'pie',
                        startAngle: 270,                        // 环图起始位置:正下发
                        center: ['25%', '45%'],                 // 圆环中心相对于容器位置
                        radius: ['40%', '50%'],                 // 圆环内径外径
                        avoidLabelOverlap: false,
                        label: {
                            normal: {
                                show: true,
                                position: 'center',
                                formatter: 'Ln'
                            }

                        },

                        data: [{
                            name: 'Ln1占比',
                            value: (180 / 360) * 100,

                            itemStyle: {
                                normal: {
                                    color: this.color
                                }
                            }
                        }, {
                            name: '总数',
                            value: 100 - (180 / 360) * 100,
                            label: {
                                normal: {
                                    show: false,
                                    fontSize: 0
                                }
                            },
                            itemStyle: {
                                normal: {
                                    color: '#02364F'
                                },
                                emphasis: {
                                    color: '#02364F'
                                }
                            },
                            hoverAnimation: false
                        }]
                    },
                    {
                        name: '',
                        type: 'pie',
                        startAngle: 270,                        // 环图起始位置:正下发
                        center: ['25%', '45%'],                 // 圆环中心相对于容器位置
                        radius: ['20%', '30%'],                 // 圆环内径外径
                        avoidLabelOverlap: false,
                        label: {
                            normal: {
                                show: true,
                                position: 'center',
                                formatter: 'Ln'
                            }

                        },

                        data: [{
                            name: 'Ln1占比',
                            value: (180 / 360) * 100,

                            itemStyle: {
                                normal: {
                                    color: '#02364F'
                                },
                                emphasis: {
                                    color: '#02364F'
                                }
                            }
                        }, {
                            name: '总数',
                            value: 100 - (180 / 360) * 100,
                            label: {
                                normal: {
                                    show: false,
                                    fontSize: 0
                                }
                            },
                            itemStyle: {
                                normal: {
                                    
                                    color: this.color
                                }
                            },
                            hoverAnimation: false
                        }]
                    },
                ]
            })
        }
    }
}
</script>
--父页面
                           <el-col :span="24">
                                <el-col :span="4">
                                    <!-- 改成组件化 -->
                                    <pie-charts :color="color1"/>
                                </el-col>
                                <el-col :span="4">
                                    <pie-charts :color="color2"/>
                                </el-col>
                                <el-col :span="4">
                                    <pie-charts :color="color3"/>
                                </el-col>
                                <el-col :span="4">
                                    <pie-charts :color="color4" />
                                </el-col>
                                <el-col :span="4">
                                    <pie-charts :color="color5"/>
                                </el-col>
                                <el-col :span="4">
                                    <pie-charts :color="color6"/>
                                </el-col>

                            </el-col>
--在原先页面data(){}中定义数据
            color1: "#8A2BE2",
            color2: "#483D8B",
            color3: "#0000FF",
            color4: "#00FFFF",
            color5: "#7FFF00",
            color6: "#FFD700",
            color7: "#8A2BE2",

搞定收工!

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐