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 }
]
}
}
}
}