vue+echarts 实现点击切换数据(监听值的变化重新渲染)
vue(elementUi)+echarts实现点击切换数据
-
前言
最近有个需求,需要按日、按天、按年去统计来自不同渠道的订单。最开始实现单个渠道去引用echarts组件,是没什么问题,但是多个渠道,就想着加上不同的按钮去请求后端。刚用vue不久,最开始查了许多资料都没什么用,后面终于整出来了,这里记录一下,也给大家分享一下。
-
先看看效果(横坐标为不同渠道,就不展示了)
echart实现效果
-
相关代码
引用echart组件
import NowChart from 'xxxx组件相关路径'
data(){
return {
type:'1'
}
},
components: {
NowChart
}
<div>
<el-radio-group v-model="type" size="small" @change="changeType">
<el-radio-button label="1">当日订单</el-radio-button>
<el-radio-button label="2">全部订单</el-radio-button>
</el-radio-group>
</div>
<now-chart v-bind:type="type"/>
关键主要在于 v-bind:type=“type” 绑定值 然后点击单选按钮时changeType 方法去改变type的值
- echarts组件相关代码
props: {
type:{
type: String,
default:'1',
required: true,
}
使用watch去监听type值的变化,然后重新渲染echarts(watch节点与data节点统计)
watch:{
type:{
handler(newValue,oldValue){
this.type=newValue;
this.initChart();
}
}
},
initCharts()方法中主要拿this.type去调用接口,然后重新渲染echarts中的值哦
- 结束
主要关键点在于父组件要绑定传值,然后echarts组件页面需要用watch监听值的变化,然后重新渲染下页面,便可以了。
-
更新(2020.8.24)
因之前时间关系,只把关键性的东西列出来了,可能有部分老铁看不太明白,今天有时间更新下完整版的。
-
首先你得有一个静态的echarts图表组件画好,可以直接去echarts官网下载对应的模板【echarts实例】,然后结合vue先弄个静态的echarts页面出来,这里我的静态的已经删了,我把我最后交互的列出来给大家看下(着重看注释部分)
<template> <!--绘制echarts--> <div :class="className" :style="{height:height,width:width}" /> </template> <script> import echarts from 'echarts' require('echarts/theme/macarons') // echarts theme import { debounce } from '@/utils' import { getNowChartData } from '@/api/data/orderChart' export default { props: { className: { type: String, default: 'chart' }, width: { type: String, default: '100%' }, height: { type: String, default: '500px' }, autoResize: { type: Boolean, default: true }, type:{ //此处为接收父类传递的参数,进行点击切换数据,默认值为1 type: String, default:'1', required: true, } }, data() { return { chart: null, sidebarElm: null, chartData: { //此处为各个坐标需要的数据的字段 channel:[], //渠道 xdCounts:[], //下单量 successCounts:[], //成功量 failCounts:[], //失败量 closeCounts:[] //关闭量 }, } }, watch:{ //此处为关键,监听type值得变化,进行echarts渲染 type:{ handler(newValue,oldValue){ this.type=newValue; this.initChart(); //值发生改变则渲染一次echarts } } }, mounted() { this.initChart(); //初始化echarts //监听侧边栏 if (this.autoResize) { this.__resizeHandler = debounce(() => { if (this.chart) { this.chart.resize() } }, 100) window.addEventListener('resize', this.__resizeHandler) } // 监听侧边栏的变化 this.sidebarElm = document.getElementsByClassName('sidebar container')[0] this.sidebarElm && this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler) }, beforeDestroy() { if (!this.chart) { return } if (this.autoResize) { window.removeEventListener('resize', this.__resizeHandler) } this.sidebarElm && this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler) this.chart.dispose() this.chart = null }, methods: { sidebarResizeHandler(e) { if (e.propertyName === 'width') { this.__resizeHandler() } }, //给echarts各个坐标赋值 setOptions({ channel, xdCounts,successCounts,failCounts,closeCounts } = {}) { this.chart.setOption({ tooltip: { trigger: 'axis', axisPointer: { type: 'cross', crossStyle: { color: '#999' } } }, toolbox: { }, xAxis: { type: 'category', data: this.chartData.channel, axisPointer: { type: 'shadow' } }, yAxis:[{ type: 'value', name: '订单量', yAxisIndex: 0, axisLabel: { formatter: '{value}', }, }], legend: { data: ['下单量','完工量','失败量','关闭量'] }, series: [ { name: '下单量', type: 'bar', data: this.chartData.xdCounts, itemStyle: { normal: { color : '#00BFFF' } } }, { name: '完工量', type: 'bar', data: this.chartData.successCounts, itemStyle: { normal: { color : '#3CB371' } } }, { name: '失败量', type: 'bar', data: this.chartData.failCounts, itemStyle: { normal: { color : ' #DB7093' } } }, { name: '关闭量', type: 'bar', data: this.chartData.closeCounts, itemStyle: { normal: { color : '#7B68EE' } } } ] }) }, //渲染echarts方法 initChart() { //调用后端接口,获取对应得数据 getNowChartData().then(re=>{ //此处根据type切换对应得值。根据后端接口来,我这里是将所以得值带过来了取不同得字段 if (this.type==1){ //当日数据 this.chartData.channel=re.channel; this.chartData.xdCounts=re.xdCounts; this.chartData.successCounts=re.successCounts; this.chartData.failCounts=re.failCounts; this.chartData.closeCounts=re.closeCounts; } else{ this.chartData.channel=re.channel; this.chartData.xdCounts=re.sumOrder; this.chartData.successCounts=re.sumSuccess; this.chartData.failCounts=re.sumFail; this.chartData.closeCounts=re.sumClose; } //关键代码,渲染 this.chart = echarts.init(this.$el, 'macarons') this.setOptions(this.chartData) }) } } } </script>
-
接下来我们进行点击按钮页面的实现。
这里我就全部结合完整代码给注释解析了,不单独拿出了。关键性的东西,看没更新之前的哦。
<template> <div class="dashboard-container"> <div class="dashboard-editor-container"> <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;"> <div> <el-radio-group v-model="type" size="small" @change="changeType"> <el-radio-button label="1">当日订单</el-radio-button> <el-radio-button label="2">全部订单</el-radio-button> </el-radio-group> </div> <now-chart v-bind:type="type"/> //此处为关键。引入echarts组件,并通过v-bind:type 去绑定对应的值 </el-row> </div> </div> </template> <script> import NowChart from '@/views/data/order/chat/OrderNowChart' export default { name: 'Dashboard', data(){ return { type:'1', //定义一个字段 } }, components: { NowChart //给组件取个别名 }, methods:{ //当选框选择值进行改变 changeType(value){ console.log("当前选中:"+value) this.type=value; }, } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .dashboard-editor-container { padding: 18px 22px 22px 22px; background-color: rgb(240, 242, 245); .chart-wrapper { background: #fff; padding: 16px 16px 0; margin-bottom: 32px; } } </style>
-
最后我们的绑定实现点击切换数据就完成了。后面我的日统计、月统计、年统计根据不同渠道去点击切换,都是类似这样实现的。用的同一个echarts模板,渲染不同数据而已。大家可以试下,用选项卡的,都是类似的
以下为纯静态模板切换源码
更多推荐
所有评论(0)