目录
组件代码
<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树
都已经更新完成了
,如果我把数值改变也集成到按钮中,那么依然是打印的旧数据;