19.vue中封装echarts组件

19.vue中封装echarts组件

1.效果图

在这里插入图片描述

2.echarts组件

npm install echarts

在这里插入图片描述

<template>
  <div ref="echart" style="height:100%;">echarts组件</div>
</template>

<script>
import echarts from 'echarts'
export default {
  props: {
    chartData: {
      type: Object,
      default() {
        return {
          xData: [],
          series: []
        }
      }
    },
    isAxisChart: {
      type: Boolean,
      default: true
    }
  },
  watch: {
    chartData: {
      handler: function() {
        this.initChart()
      },
      deep: true
    },
    isCollapse() {
      setTimeout(() => {
        this.resizeChart()
      }, 300)
    }
  },
  computed: {
    options() {
      return this.isAxisChart ? this.axisOption : this.normalOption
    },
    isCollapse() {
      return this.$store.state.tab.isCollapse
    }
  },
  data() {
    return {
      echart: null,
      axisOption: {
        legend: {
          textStyle: {
            color: '#333'
          }
        },
        grid: {
          left: '10%'
        },
        tooltip: {
          trigger: 'axis'
        },
        xAxis: {
          type: 'category',
          data: [],
          axisLine: {
            lineStyle: {
              color: '#17b3a3'
            }
          },
          axisLabel: {
            color: '#333'
          }
        },
        color: ['#2ec7c9', '#b6a2de', '#5ablef'],
        yAxis: {
          type: 'value',
          axisLine: {
            lineStyle: {
              color: '#17b3a3'
            }
          }
        },
        series: []
      },
      normalOption: {
        tooltip: {
          trigger: 'item'
        },
        series: [
          {
            type: 'pie',
            data: []
          }
        ]
      }
    }
  },
  methods: {
    // 初始化图表
    initChart() {
      this.initChartData()
      if (this.echart) {
        this.echart.setOption(this.options)
      } else {
        this.echart = echarts.init(this.$refs.echart)
        this.echart.setOption(this.options)
      }
    },
    initChartData() {
      if (this.isAxisChart) {
        console.log('有坐标轴')
        this.axisOption.xAxis.data = this.chartData.xData
        this.axisOption.series = this.chartData.series
      } else {
        this.normalOption.series = this.chartData.series
        console.log(this.normalOption)
        console.log('没有坐标轴')
      }
    },
    resizeChart() {
      if (this.echart) {
        this.echart.resize()
      }
    }
  },
  mounted() {
    window.addEventListener('resize', this.resizeChart)
  },
  destroyed() {
    window.removeEventListener('resize', this.resizeChart)
  }
}
</script>

<style lang="scss" scoped></style>

3.使用组件

按照组件格式整理好数据格式
传入组件

home.vue

<template>
  <div>
    <el-row :gutter="20">
      <el-col :span="6"
        ><el-card>
          <div class="top-card">
            <div class="content-label">
              <span class="content-label-title">{{ $t('lang.newMembers') }}</span>
              <span class="content-label-num">20</span>
            </div>
            <div class="content-chart">
              <el-progress type="circle" :percentage="25"></el-progress>
            </div>
          </div> </el-card
      ></el-col>
      <el-col :span="6"
        ><el-card>
          <div class="top-card">
            <div class="content-label">
              <span class="content-label-title">{{ $t('lang.getCoupons') }}</span>
              <span class="content-label-num">20</span>
            </div>
            <div class="content-chart">
              <el-progress type="circle" :percentage="100" status="success"></el-progress>
            </div>
          </div> </el-card
      ></el-col>
      <el-col :span="6"
        ><el-card>
          <div class="top-card">
            <div class="content-label">
              <span class="content-label-title">{{ $t('lang.memIntegral') }}</span>
              <span class="content-label-num">20</span>
            </div>
            <div class="content-chart">
              <el-progress type="circle" :percentage="70" status="warning"></el-progress>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6"
        ><el-card>
          <div class="top-card">
            <div class="content-label">
              <span class="content-label-title">{{ $t('lang.registerUser') }}</span>
              <span class="content-label-num">20</span>
            </div>
            <div class="content-chart">
              <el-progress type="circle" :percentage="50" status="exception"></el-progress>
            </div>
          </div> </el-card
      ></el-col>
    </el-row>
    <el-row :gutter="20">
      <el-col :span="12">
        <el-card class="table-card-table">
          <common-table :tableData="memberList" :tableLabel="memberListLabel"></common-table>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card class="table-card">
          <div class="chart-wrapper"><common-echarts :chartData="echartData.merberLine"></common-echarts></div>
        </el-card>
        <el-card class="table-card-tow">
          <div class="table-card-tow-wrapper">
            <div class="left"><common-echarts :chartData="echartData.merberBar"></common-echarts></div>
            <div class="right">
              <common-echarts :chartData="echartData.merberPie" :isAxisChart="false"></common-echarts>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import CommonTable from '@/components/table/CommonTable.vue'
import CommonEcharts from '@/components/echarts/CommonEcharts.vue'
export default {
  components: {
    CommonTable,
    CommonEcharts
  },
  data() {
    return {
      // 表格数据
      memberList: [],
      echartData: {
        merberLine: {
          xData: [],
          series: []
        },
        merberBar: {
          xData: [],
          series: []
        },
        merberPie: {
          series: []
        }
      }
    }
  },
  computed: {
    // 表格label标签
    memberListLabel() {
      return [
        {
          label: this.$t('lang.month'),
          prop: 'month'
        },
        {
          label: this.$t('lang.newMembers'),
          prop: 'addMember'
        },
        {
          label: this.$t('lang.memIntegral'),
          prop: 'addIntegral'
        },
        {
          label: this.$t('lang.getCoupons'),
          prop: 'getCoupons'
        },
        {
          label: this.$t('lang.registerUser'),
          prop: 'registerUser'
        }
      ]
    }
  },
  created() {
    console.log(this.memberListLabel)
    this.getMembers()
  },
  methods: {
    getMembers() {
      this.$api.getHomeApi.getMembersList().then(res => {
        console.log(res)
        this.memberList = res.data.data
        // 会员折线图
        const merberLine = res.data.data
        const merberLineXdata = []
        for (let i = 0; i < merberLine.length; i++) {
          merberLineXdata[i] = merberLine[i].month
        }
        // 折线图x轴
        this.echartData.merberLine.xData = merberLineXdata
        // 柱状图x轴
        this.echartData.merberBar.xData = merberLineXdata
        // 折线图y轴数据
        const obj1 = {
          name: '新增会员',
          data: [],
          type: 'line'
        }
        for (let i = 0; i < merberLine.length; i++) {
          obj1.data[i] = merberLine[i].addMember
        }
        this.echartData.merberLine.series.push(obj1)
        const obj2 = {
          name: '新增积分',
          data: [],
          type: 'line'
        }
        for (let i = 0; i < merberLine.length; i++) {
          obj2.data[i] = merberLine[i].addIntegral
        }
        this.echartData.merberLine.series.push(obj2)
        // 柱状图y轴数据
        const obj3 = {
          name: '新增会员',
          data: [],
          type: 'bar'
        }
        for (let i = 0; i < merberLine.length; i++) {
          obj3.data[i] = merberLine[i].addMember
        }
        this.echartData.merberBar.series.push(obj3)
        const obj4 = {
          name: '新增积分',
          data: [],
          type: 'bar'
        }
        for (let i = 0; i < merberLine.length; i++) {
          obj4.data[i] = merberLine[i].addIntegral
        }
        this.echartData.merberBar.series.push(obj4)
        // 饼图数据
        const obj5 = {
          name: '积分占比图',
          type: 'pie',
          radius: ['30%', '70%'],
          avoidLabelOverlap: false,
          data: []
        }
        for (let i = 0; i < merberLine.length; i++) {
          obj5.data[i] = merberLine[i].month
          obj5.data[i] = merberLine[i].addIntegral
        }
        this.echartData.merberPie.series.push(obj5)
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.el-card {
  height: 170px;
}
.top-card {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: row;
}
.content-label {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 180px;
}
.content-label-title {
  font-size: 25px;
}
.content-label-num {
  margin-top: 30px;
  font-size: 20px;
}
.content-chart {
  height: 100%;
}
.table-card-table {
  margin-top: 20px;
  height: 520px;
}
.table-card {
  margin-top: 20px;
  height: 250px;
}
.chart-wrapper {
  height: 250px;
  width: 100%;
}
.table-card-tow {
  margin-top: 20px;
  height: 250px;
}
.table-card-tow-wrapper {
  display: flex;
  width: 100%;
  height: 250px;
}
.left {
  flex: 1;
  width: 50%;
  height: 250px;
}
.right {
  flex: 1;
  width: 50%;
  height: 250px;
}
</style>

4.接口返回数据格式

// 导入mockjs 使用数据
// import Mock from 'mockjs'
export default {
  getmembers: () => {
    return {
      code: 2000,
      data: {
        data: [
          { id: '001', month: '1月', addMember: 1, addIntegral: 2, getCoupons: 221, registerUser: 431 },
          { id: '002', month: '2月', addMember: 2, addIntegral: 4, getCoupons: 222, registerUser: 530 },
          { id: '003', month: '3月', addMember: 3, addIntegral: 6, getCoupons: 223, registerUser: 630 },
          { id: '004', month: '4月', addMember: 4, addIntegral: 3, getCoupons: 221, registerUser: 431 },
          { id: '005', month: '5月', addMember: 5, addIntegral: 2, getCoupons: 222, registerUser: 530 },
          { id: '006', month: '6月', addMember: 6, addIntegral: 1, getCoupons: 223, registerUser: 630 }
        ]
      }
    }
  }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值