文章目录
- 写在前面
- 需求①
- 需求②
- 需求③
- 无效的解决办法1:
- 无效的解决办法2
- 有效的解决办法
写在前面
我太难了,搞一个echart仪表盘,需求一步步分解:
①一开始是写死的假数据,图表成功显示在页面上;
②和后台约定数据类型格式,前台写好接口,请求后台数据,替换掉假数据给图表data赋值真实数据并成功渲染;
③我想每隔5秒调用一次请求获取数据,然后刷新图表,重新渲染出来。这里涉及到了timer定时器和watch监听数据变化的知识。
④终于在刚刚解决了。我草(一种植物)拟大爷…
需求①
先上代码:
<template><div :class="className" :style="{height:height,width:width}" />
</template><script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'export default {mixins: [resize],props: {className: {type: String,default: 'chart'},width: {type: String,default: '100%'},height: {type: String,default: '300px'},autoResize: {type: Boolean,default: true}},data() {return {}},created () {this.$nextTick(() => {this.initChart()})},beforeDestroy() {if (!this.chart) {return}this.chart.dispose()this.chart = null},methods: {initChart () {// 基于准备好的dom,初始化echarts实例this.chart = echarts.init(this.$el, 'macarons')//绘制图表,option是图表数据this.chart.setOption({title: {text: 'CPU使用情况'},tooltip: {formatter: "{a} <br/>{b} : {c}%"},series: [{name: 'cpu仪表盘',type: 'gauge',min: 0, // 最小值max: 100, // 最大值precision: 0, // 小数精度,默认为0,无小数点detail: {formatter: '{value}%'},data: [{ value: 30, name: 'CPU占用率' }],}]})},}
}
</script>
再上图表:
到这里很简单,不用多说~
需求②
这里开始就遇到一堆问题了,总结几个问题如下:
问题① 和后台约定数据格式。 返回数据类型是什么? json对象?json字符串?
里面内容是什么,需要约定code请求码吗? (vue封装的request.js请求,判断返回成功必须有状态码,设置20000。所以得让后端返回数据内部加个code)
这里两处大的错误,随后解决。
传送门:① json解析数据问题
②数据未添加code状态码
问题② 前台写好接口,请求后台数据。 接口怎么写?如何能访问到后台?
不得不说菜的很,这里也搞了半天才成功访问到后台。
就拿我图表来说:
首先,我要在项目目录的api目录下,新建一个接口文件。比如cpu.js 具体代码如下:
import request from "@/utils/request"// 这就是接口函数
export function getCpuData() {return request({url: '/cpu', //这是自定义的前台url,随意method: 'get', // 获取后台数据, get请求})
}
其次,vue.config.js文件配置你当前url访问的后台url。很重要直接决定你访问后台成不成功。来看下面关键配置:
vue.config.js
devServer: {port: port,open: true,overlay: {warnings: false,errors: true},//before: require('./mock/mock-server.js'), /*注释掉这行代码*/proxy: {'/cpu' : {target: 'xxx', // 你的后台接口url地址changeOrigin: true, // 跨域pathRewrite: {'^/cpu': '/cpu'}},},
这里也容易有问题,比如后台提供你的是 127.0.0.1:8081/cpu 。那在代理转发target处要写成 ‘127.0.0.1:8080/’ 语法规则会默认将 开头的 '/cpu’和target合并的。我之前就是直接写的接口地址。结果访问不到。注意一下。
第三步, 修改图表,将假数据变成调用接口获取真实数据。
直接上图表代码:
<template><div :class="className" :style="{height:height,width:width}" />
</template><script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
import { getCpuData } from "@/api/cpu"export default {mixins: [resize],props: {className: {type: String,default: 'chart'},width: {type: String,default: '100%'},height: {type: String,default: '200px'},autoResize: {type: Boolean,default: true}},data () {return { // 改动一option: {title: {text: 'CPU使用情况'},tooltip: {formatter: "{a} <br/>{b} : {c}%"},series: [{name: 'cpu仪表盘',type: 'gauge',min: 0, // 最小值max: 100, // 最大值precision: 0, // 小数精度,默认为0,无小数点detail: {formatter: '{value}%'},data: [], }]},}},mounted () {this.$nextTick(() => {this.initChart()})},methods: {// 初始化图表initChart () {// 基于准备好的dom,初始化echarts实例this.chart = echarts.init(this.$el, 'macarons')//绘制图表,option是图表数据 // 改动二// let option = {// title: {// text: 'CPU使用情况'// },// tooltip: {// formatter: "{a} <br/>{b} : {c}%"// },// series: [// {// name: 'cpu仪表盘',// type: 'gauge',// min: 0, // 最小值// max: 100, // 最大值// precision: 0, // 小数精度,默认为0,无小数点// detail: {// formatter: '{value}%'// },// data: [// { value: this.cpuData * 100, name: 'CPU占用率' }// ],// }// ]// }this.drawData() // 改动三//this.chart.setOption(this.option, true)},// 获取后台数据 // 最重要的改动四drawData () {getCpuData().then(res => {let code = res["code"]if (code == 20000) {console.log(res)this.cpuData = res["cpu"]["pct"];// 赋值给图表datathis.option.series[0].data.push({name: 'CPU占用率',value: Math.round(this.cpuData * 100)});this.chart.setOption(this.option, true)} else {alert("get failed")}console.log(this.cpuData)})},}
}
</script>
以上,跟第一版图表代码比较,里面有几处大的改动。
一. 将绘制图表的option数据从methods里拿出来放到了data()中;
二. 添加接口回调函数,绘制图表数据函数setOption放在了接口回调函数内部。
关键点:
①约定状态码,确认收到数据;
②数据格式确认,我的例子此处是json对象,故直接以数组形式就可直接赋值给临时变量;
③将临时变量的值添加到option的对应位置处。
④调用setOption绘制图表。
现在,你可以看到你的图标数据渲染就是你后台获得的真实数据
看图:
需求③
现在我们要每隔5秒向后台拿一次数据,然后前台重新渲染一遍。这里涉及到了定时器、watch监听、图表渲染清除上一次数据几个关键点。
查了数不清的资料一遍一遍尝试终于可以了。想流泪~~~
直接上高速:
<template><div :class="className" :style="{height:height,width:width}" />
</template><script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
import { getCpuData } from "@/api/cpu"export default {mixins: [resize],props: {className: {type: String,default: 'chart'},width: {type: String,default: '100%'},height: {type: String,default: '200px'},autoResize: {type: Boolean,default: true}},data () {return {option: {title: {text: 'CPU使用情况'},tooltip: {formatter: "{a} <br/>{b} : {c}%"},series: [{name: 'cpu仪表盘',type: 'gauge',min: 0, // 最小值max: 100, // 最大值precision: 0, // 小数精度,默认为0,无小数点detail: {formatter: '{value}%'},data: [],}]},}},watch: {// 观察cpu_option的变化option: {handler(newVal, oldVal) {this.timer()this.destroyed()},deep: true //对象内部属性的监听},},mounted () {this.$nextTick(() => {this.initChart()})},methods: {// 初始化图表initChart () {// 基于准备好的dom,初始化echarts实例this.chart = echarts.init(this.$el, 'macarons')this.drawData()},// 获取后台数据drawData () {getCpuData().then(res => {let code = res["code"]if (code == 20000) {console.log(res)this.option.series[0].data = [] // 这里涉及致命问题,下面解释this.cpuData = res["cpu"]["pct"];// 赋值给图表datathis.option.series[0].data.push({name: 'CPU占用率',value: Math.round(this.cpuData * 100)});//绘制图表数据this.chart.setOption(this.option, true)} else {alert("get failed")}console.log(this.cpuData)})},//这是一个定时timer () {return setTimeout(() => {this.drawData()}, 5000)},// 销毁定时器destroyed () {clearTimeout(this.timer())}}
}
</script>
我直接说如何每次刷新图表都清除上一次渲染的数据。
无效的解决办法1:
this.chart.setOption(option,true) 无效
无效的解决办法2
this.chart.clear() 无效
有效的解决办法
this.option.series[0].data = []
即在下一次获取数据渲染图表前先将上一次赋的数据清空!!!!!
否则,你会看到,一个仪表盘百分比一直保持第一次获取数据不变,而指针每5秒增加一个,最后成了千手观音,那画面简直太美。。。
以上就是我所一路坎坷总结。如有不成熟的地方还请谅解。如有更好的解决办法还请不吝赐教。我虚心好学~