Vue解决CDN引入的echarts,通过ajax异步请求的数据不能被正确渲染到视图层的问题
Vue解决CDN引入的echarts,通过ajax异步请求的数据不能被正确渲染到视图层的问题
在参加计算机设计大赛做作品的时候遇到的一个困难,花了挺长时间才解决,在这里做个记录。
一、这里先介绍如何CDN引入ECharts:
在需要用到ECharts的界面加入
<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.1/dist/echarts.js"></script>
即可,或者先下载好这个文件,src改为这个文件的相对路径。
二、以南丁格尔玫瑰图为例(我的项目是用了这个图表)
先看ECharts示例完整代码
示例是直接在script中演示效果,所有数据都是写死的
而我们用Vue的目的就是实现根据请求后端返回的数据对视图层进行动态的渲染,保证每次请求返回的数据都能被正确地渲染到视图层上。
html:
<div id="illegal" style="width: 1000;height: 650px;"> </div>
在Vue实例对象的data中写上要被动态渲染的数据:
data:{
viewBehavior: {
转让通行证: 0,
伪造通行证: 0,
售卖通行证: 0,
拆卸通行证: 0,
借予他人使用: 0,
故意损坏或涂鸦通行证: 0,
行驶速度过快: 0,
未佩戴安全头盔: 0,
未在规定区域停放: 0,
未在规定区域充电: 0,
}
}
然后这些数据都是通过mounted钩子函数去执行methods封装了ajax请求的函数getViolations返回回来的。
methods:{
//获取某违规情况
getViolations(stringValue) { // 参数stringValue 如 “行驶速度过快”
var that = this;
$.ajax({
url: '接口地址',
data: {
key: "behavior",
value: stringValue
},
// async: false,
type: "POST",
success(res) {
if (res.error_code == 0) {
Vue.set(that.viewBehavior, stringValue, res.length);
console.log(stringValue + ":" + that.viewBehavior[stringValue]);
} else if (res.error_code == 1) {
console.log(res.msg);
}
},
error() {
that.$Message.error({
content: res.msg
});
}
})
},}
因为我写的接口是根据key:value查询来返回数据,
所以在mounted钩子函数用for循环去请求viewBehavior中各项数据(注意values数组各元素要对应Vue实例对象data里的viewBehavior对象的属性(左值))
mounted:{
var values = ['转让通行证', '伪造通行证', '售卖通行证', '拆卸通行证', '借予他人使用',
'故意损坏或涂鸦通行证', '行驶速度过快', '未佩戴安全头盔', '未在规定区域停放', '未在规定区域充电'
];
// 获取各类违规情况的人数
for (var i = 0; i < values.length; i++) {
that.getViolations(values[i]); //调用包含ajax的获取数据的函数
}
}
然后各种百度后其实都没有找到合理的解决方案。就自己仔细琢磨了一下示例代码。
我的第一次错误的做法:就是直接把ECharts一大段示例代码直接搬到Vue实例对象的mounted钩子函数中,只把从mounted钩子函数中var出来的option中的series中的data中的各项value赋值为Vue实例对象data中viewBehavior中的各值
data: [
{value: that.viewBehavior['转让通行证'],name: '转让通行证'},
{value: that.viewBehavior['伪造通行证'],name: '伪造通行证'},
{value: that.viewBehavior['售卖通行证'],name: '售卖通行证'},
{value: that.viewBehavior['拆卸通行证'],name: '拆卸通行证'},
{value: that.viewBehavior['借予他人使用'],name: '借予他人使用'},
{value: that.viewBehavior['故意损坏或涂鸦通行证'],name: '故意损坏、涂鸦通行证'},
{value: that.viewBehavior['行驶速度过快'],name: '行驶速度过快'},
{value: that.viewBehavior['未佩戴安全头盔'],name: '未佩戴安全头盔'},
{value: that.viewBehavior['未在规定区域停放'],name: '未在规定区域停放'},
{value: that.viewBehavior['未在规定区域充电'],name: '未在规定区域充电'}
],
然而,页面在加载的时候,老是渲染不出正确的后台数据(有时候全是0,有时候很多项是0)。
于是尝试
setTimeout(function(){
option && myChart.setOption(option);
},4000)
去延迟myChart的渲染。结果发现数据能大概率(注意是概率)正确渲染了。但是这种方法是不能根除问题的!再缩短一下延迟时间比如1秒,它又不能正确渲染了。
那就找到问题所在了:
数据在还没请求完毕,视图就被渲染,而且viewBehavior各属性默认值是0。
那怎么办?当即就想到等ajax请求完数据了,再往下执行代码呗。
然后我就把ajax的async配置项设为false(同步请求)
async:false
后台返回的数据的的确确100%能正确渲染到视图层了,但是加载速度实在是太慢了!,加载没完成什么都动不了,当我频繁切换页面的时候,点这个用到ECharts的页面就会因为ajax请求卡很久。
隔了一个星期,又想到一个不规范的方法,把setTimeout改为setInterval。对EChart视图进行定时渲染,每隔1秒渲染一遍。(视图会每隔1s更新一次,第一次渲染的数据也是很难完全请求完毕的)
setInterval(function(){
option && myChart.setOption(option);
},1000)
这种方法的确可以保证最后的视图能根据最后的viewSort数据被正确渲染,但是正确渲染后,它还在不断地渲染(虽然用户看不出来,但是这种做法是作为一个合格程序员的低级做法,也没有用到Vue正确的MVVM原理)。
随后在床上睡觉突然来了灵感
正确做法:
每次ajax请求会修改Vue实例对象中的data中的viewBehavior中某属性的值。
那我们就深度监视viewBehavior中某属性被修改的时候,去重新渲染视图就好了呀!
watch: {
viewBehavior: {
deep: true,
handler() {
//保存一下this
var that = this;
var chartDom = document.getElementById('illegal');
var myChart = echarts.init(chartDom);
/*echarts start*/
//option 开始
/* 指定图表的配置项和数据 */
var option = {
legend: { //图例组件
bottom: '10px', //图例组件(即颜色分类说明图标)离容器上侧的距离
},
toolbox: { //工具栏组件相关行为
show: true,
feature: {
mark: {
show: true
},
restore: {
show: true
},
// 还原
saveAsImage: {
show: true
} //保存为图
}
},
title: {
text: '各类违规情况人数及其占比',
top: '30px',
left: 'center'
},
// series start
series: [ //“事件”
{
name: 'Nightingale Chart', //访问来源
type: 'pie', //饼状图
radius: [50, 200],
center: ['50%', '50%'],
roseType: 'area',
/*'radius' 扇区圆心角展现数据的百分比,半径展现数据的大小。
'area' 所有扇区圆心角相同,仅通过半径展现数据大小。*/
itemStyle: {
normal: {
label: {
show: true,
formatter: '{b} : {c} ({d}%)'
},
labelLine: {
show: true
},
borderRadius: 8,
},
},
data: [{
value: that.viewBehavior['转让通行证'],
name: '转让通行证'
}, {
value: that.viewBehavior['伪造通行证'],
name: '伪造通行证'
}, {
value: that.viewBehavior['售卖通行证'],
name: '售卖通行证'
}, {
value: that.viewBehavior['拆卸通行证'],
name: '拆卸通行证'
}, {
value: that.viewBehavior['借予他人使用'],
name: '借予他人使用'
}, {
value: that.viewBehavior['故意损坏或涂鸦通行证'],
name: '故意损坏、涂鸦通行证'
}, {
value: that.viewBehavior['行驶速度过快'],
name: '行驶速度过快'
}, {
value: that.viewBehavior['未佩戴安全头盔'],
name: '未佩戴安全头盔'
}, {
value: that.viewBehavior['未在规定区域停放'],
name: '未在规定区域停放'
}, {
value: that.viewBehavior['未在规定区域充电'],
name: '未在规定区域充电'
}, ],
},
]
// series end
};
//option结束
// echarts大饼图end
// 渲染视图
option && myChart.setOption(option);
}
}
},
现在ajax能异步请求,又能根据显示后台请求返回的数据正确渲染到视图了!
至此,感谢阅读我的文章,如果对你有用,请点个赞赞 ❤
更多推荐
所有评论(0)