【Vue】记录一个饼状图组件的使用

43 篇文章 4 订阅

组件代码

<template>
  <div :class="className" :style="{height:height,width:width}" />
</template>

<script>
import * as echarts from 'echarts'

require('echarts/theme/macarons') // echarts 主题
import resize from './mixins/resize'
import { getLanguage } from '@/utils/language'

// 初始化后端参数对应的前端展示name值
const leMap = {
  age0to18: '0-18',
  age19to35: '19-35',
  age36to55: '36-55',
  age56to75: '56-75',
  age75plus: '75+'
}
export default {
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '300px'
    },
    // 传参饼图数据
    charData: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      chart: null,
      isCN: false
    }
  },
  created() {
    this.isCN = getLanguage() === 'zh_CN'
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart()
    })
  },
  // 组件销毁时清空饼图
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    // 提供给父组件更改值以后调用,不加nexTick会导致更新失败,因为获取到的是Dom更新之前的数据
    refresh() {
      this.$nextTick(() => {
        this.initChart()
      })
    },
    // 调用这个更新饼图的数据,由于饼图是外部组件生成的所以直接修改参数不能改变样式,需要重新调用以重新加载
    // 尽量在dom更新之后再调用
    initChart() {
      console.log('调用了组件刷新方法')
      console.log(this.charData)
      // 将后端的数据格式化成组件需要的格式
      const dataList = []
      Object.keys(this.charData).forEach(key => {
        dataList.push({ name: leMap[key], value: this.charData[key] })
      })
      this.chart = echarts.init(this.$el, 'macarons')
      this.chart.setOption({
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b} : {c} ({d}%)'
        },
        legend: {
          left: 'center',
          bottom: '10',
          data: ['0-18', '19-35', '36-55', '56-75', '75+'] // 这是旁边的图例
        },
        series: [
          {
            name: '用户年龄段分布', // 指向扇形时的标题
            type: 'pie',
            roseType: 'radius',
            radius: [40, 95], // 圆的内径和外径大小
            center: ['50%', '38%'], // 饼图的横坐标和纵坐标
            data: dataList, // 这里使用上面定义的饼状图数据
            animationEasing: 'cubicInOut',
            animationDuration: 2600
          }
        ]
      })
    }
  }
}
</script>

父组件的声明以及调用

声明
<div class="chart-wrapper">
  <pie-chart ref="pieChart" :char-data="userGroupByAgeDto" />
</div>
传初始值
userGroupByAgeDto: {
  age0to18: 1,
  age19to35: 2,
  age36to55: 3,
  age56to75: 4,
  age75plus: 5
}
更新数据以后调用子组件方法重新加载数据
 this.userGroupByAgeDto = res.data.userGroupByAgeDto
 this.orderGroupByTypeDtos = res.data.orderGroupByTypeDtos
 this.$refs.pieChart.refresh() // 这里的调用一定要在子组件中声明dom刷新以后再操作

遇到的一些问题

更改传递给组件的参数以后,统计图没有更新状态

原因: 这个组件并不支持双向绑定,
解决: 所以需要我们手动调用初始化统计图的方法来进行刷新状态

更改状态以后调用子组件方法更新时打印的数据依然是旧数据,但是使用按钮调用这个方法就能正常更新状态,打印的数据也是新数据

原因:vue更新数据以后,dom并不会马上刷新,所以我们需要获取刷新后的值
解决:我们使用如下方法($nextTick)调用刷新函数

 this.$nextTick(() => {
        this.initChart()
      })

在dom树更新状态以后再调用刷新状态的函数;

至于为什么按钮可以正常获取到,因为当时我写测试按钮的时候,是手动触发刷新,而更新传值是在获取到新数据的时候就刷进去了,所以等到我点击的时候dom树都已经更新完成了,如果我把数值改变也集成到按钮中,那么依然是打印的旧数据;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值