Vue Echarts渲染数据导致残留脏数据的问题处理
作者:苏生Susheng
这篇文章主要介绍了Vue Echarts渲染数据导致残留脏数据的问题处理,文中通过代码示例给大家讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
问题背景
前提说明:
- 不同组件中都使用了Echarts
- 多个组件在一个父组件中动态渲染
- 组件中存在多种数据渲染,有Echarts,也有集合,也有文本,这些数据放在一个集合对象中返回到前端
- Echarts中的数据从数据库读取出来(返回的是一个可以直接解析的option的JSON格式的数据)
- 组件中使用mount挂载触发获取option数据
- 父组件中点击上一条、下一条存在组件切换
- 不同组件切换时,组件确实重新加载,数据重新获取,能够重新渲染
问题说明:
- 同组件的多条记录切换,组件不会动态加载,mount中不会执行获取option数据的方法
- 同组件多条记录切换,Echarts中的数据会展示之前的残留数据
- 如果返回的集合中没有option这条记录,那么有Echarts中的数据会渲染切换之前的数据
- 如果一个组件中渲染了两个Echarts,当两个option都没有数据时,第一个的确不会渲染,但是第二个渲染的还是切换之前的数据
解决
问题1解决
问题:
- 同组件的多条记录切换,组件不会动态加载,mount中不会执行获取option数据的方法
解决:
- 父组件中,根据组件名称动态赋值ref属性,根据ref属性,直接在父组件中调用加载数据的方法
<component :ref="`detail_${detailCom}`" :is="detailCom" :summaryLabel="summaryLabel" :concernDetList="concernDetailList"></component>
//页面切换
changePage(type){
if(this.concernDetailList.length === 0){
this.detailCom = "Empty"
}else {
// 根据newVal来:1、展示对应的组件,2、更新接口
if(type === "ABNORMAL_INDICATORS"){
this.detailCom = "AbnormalIndicators"
this.$refs.detail_AbnormalIndicators.getConcernDet_Msg(this.concernDetailList)
}else if(type === "EMERGENCY_PLAN"){
this.detailCom = "EmergencyPlan"
this.$refs.detail_EmergencyPlan.getConcernDet_Msg(this.concernDetailList)
}else if(type === "POLICY_INTERPRETATION"){
this.detailCom = "PolicyInterpretate"
//政策解读 待定,页面还未开发
//this.$refs.detail_PolicyInterpretate.getConcernDet_Msg(this.concernDetailList)
}else if(type === "TASK_TRACK"){
this.detailCom = "TaskTracking"
this.$refs.detail_TaskTracking.getConcernDet_Msg(this.concernDetailList)
}else if(type === "SUPERVISION_REMINDER"){
this.detailCom = "SuperveReminder"
this.$refs.detail_SuperveReminder.getConcernDet_Msg(this.concernDetailList)
}
}
},
缺陷:
- 同组件不触发动态加载不会出问题,但是不同组件或者初次进入时,组件是动态加载的,此时ref并没有赋值,因此浏览器控制台会有一个报错,不过不影响使用,就没管了
问题2解决
问题:
- 同组件多条记录切换,Echarts中的数据会展示之前的残留数据
解决: - 这个问题很简单,只需要在Echarts渲染option数据时,清除旧数据就可以了,一个参数就能搞定
- 原本是这么写的:
this.myChart.setOption(option);,现在这么写:this.myChart.setOption(option,true);,避免上一次渲染的缓存干扰
问题3解决
问题:
- 如果返回的集合中没有option这条记录,那么有Echarts中的数据会渲染切换之前的数据
this.concernDetList.forEach((item)=>{
let obj = {
"name":item.detTitle,
"value":item.columnContent1
}
if(item.sort == "1"){
//详情描述
this.detailObj = obj
}else if(item.sort == "3"){
//异常诊断
this.abnDiagnosisObj = obj
}else if(item.sort == "4"){
//建议方案推荐
this.adviceObj = obj
}else if(item.sort == "2"){
//图示区域
this.resPersonList = JSON.parse(item.columnContent2 || "[]");
this.myChart = this.$echarts.init(document.getElementById('lineEcharts'));
option = JSON.parse(item.columnContent1 || "[]");
console.log("============",option)
// 加true参数,避免上一次渲染的缓存干扰
this.myChart.setOption(option,true);
//响应屏幕宽高
window.addEventListener('resize', () => {
if (this.myChart) {
this.myChart.resize();
}
});
}
})
解决:
- 说到底还是
this.myChart.setOption(option,true);这个true的问题 - 这个问题只能在后台处理,因为想要清空上一个Echarts中的option的话,必须要进到this.sort===2这个逻辑
- 而现在的问题是后台没有查到对应的这条记录时,压根就不返回
- 因此需要在后台去判断有没有sort=2的记录,如果没有必须写一个空的返回出来,这样前端才能进到这个逻辑
问题4解决
问题:
如果一个组件中渲染了两个Echarts,当两个option都没有数据时,第一个的确不会渲染,但是第二个渲染的还是切换之前的数据
解决:尝试写了好久的逻辑,一直都不知道还有个clear方法
反正子组件不能这么写:
this.myChart.setOption([],true);,这么写会报错,直接让第二个渲染方法不执行,因此就不会渲染空数据,也就会展示残留的脏数据了用
this.myChart.clear()完美解决问题父组件
//页面切换
changePage(type){
if(this.concernDetailList.length === 0){
this.detailCom = "Empty"
}else {
// 根据newVal来:1、展示对应的组件,2、更新接口
if(type === "ABNORMAL_INDICATORS"){
this.detailCom = "AbnormalIndicators"
this.$refs.detail_AbnormalIndicators.getConcernDet_Msg(this.concernDetailList)
}else if(type === "EMERGENCY_PLAN"){
this.detailCom = "EmergencyPlan"
this.$refs.detail_EmergencyPlan.getConcernDet_Msg(this.concernDetailList)
}else if(type === "POLICY_INTERPRETATION"){
this.detailCom = "PolicyInterpretate"
//政策解读 待定,页面还未开发
//this.$refs.detail_PolicyInterpretate.getConcernDet_Msg(this.concernDetailList)
}else if(type === "TASK_TRACK"){
this.detailCom = "TaskTracking"
this.$refs.detail_TaskTracking.getConcernDet_Msg(this.concernDetailList)
}else if(type === "SUPERVISION_REMINDER"){
this.detailCom = "SuperveReminder"
this.$refs.detail_SuperveReminder.getConcernDet_Msg(this.concernDetailList)
}
}
},
// 上一条
handlePre(){
//获取上一条的ID
this.concernSummaryIndex = this.concernSummaryIndex - 1;
const concernDetId = this.followList[this.concernSummaryIndex].summaryId;
//根据上一条的ID查询对应的详情
this.changeConcernDet(concernDetId,this.followList[this.concernSummaryIndex].type);
this.summaryLabel = this.followList[this.concernSummaryIndex].summaryLabel
},
// 下一条
handleNext(){
//获取下一条的ID
this.concernSummaryIndex = this.concernSummaryIndex + 1;
const concernDetId = this.followList[this.concernSummaryIndex].summaryId;
//根据下一条的ID查询对应的详情
this.changeConcernDet(concernDetId,this.followList[this.concernSummaryIndex].type);
this.summaryLabel = this.followList[this.concernSummaryIndex].summaryLabel
},
changeConcernDet(concernDetId,type){
const concernSummaryInfoQueryVO = {"summaryId":concernDetId};
getConcernDet(concernSummaryInfoQueryVO).then((result)=>{
//更新关注事项详情
this.concernDetailList = result.data;
this.changePage(type);
});
}
- 子组件
getBarEcharts(option){
this.myChart = this.$echarts.init(document.getElementById('barEcharts'));
if(option.length === 0) {
this.myChart.clear()
}else{
//图示区域
//let option = JSON.parse(item.columnContent1 || "[]");
// 加true参数,避免上一次渲染的缓存干扰
this.myChart.setOption(option,true);
//响应屏幕宽高
window.addEventListener('resize', () => {
if (this.myChart) {
this.myChart.resize();
}
});
}
},
getZhuEcharts(option){
this.myChart2 = this.$echarts.init(document.getElementById('zhuEcharts'));
if(option.length === 0) {
this.myChart2.clear()
}else{
//let option = JSON.parse(item.columnContent2 || "[]");
// 加true参数,避免上一次渲染的缓存干扰
this.myChart2.setOption(option,true);
//响应屏幕宽高
window.addEventListener('resize', () => {
if (this.myChart2) {
this.myChart2.resize();
}
});
}
},
getConcernDet_Msg(list){
this.detailObj={}
this.myChart2 = null;
this.myChart = null;
if(list){
this.concernDetList = list;
}
this.concernDetList.forEach((item)=>{
if(item.sort == "1"){
let obj = {
"name":item.detTitle,
"value":item.columnContent1
}
//详情描述
this.detailObj = obj
}else if(item.sort == "2"){
this.getBarEcharts(JSON.parse(item.columnContent1 || "[]"))
this.getZhuEcharts(JSON.parse(item.columnContent2 || "[]"))
}
})
},
以上就是Vue Echarts渲染数据导致残留脏数据的问题处理的详细内容,更多关于Vue Echarts渲染后残留脏数据的资料请关注脚本之家其它相关文章!
