Vue Echarts渲染數(shù)據(jù)導(dǎo)致殘留臟數(shù)據(jù)的問題處理
問題背景
前提說明:
- 不同組件中都使用了Echarts
- 多個組件在一個父組件中動態(tài)渲染
- 組件中存在多種數(shù)據(jù)渲染,有Echarts,也有集合,也有文本,這些數(shù)據(jù)放在一個集合對象中返回到前端
- Echarts中的數(shù)據(jù)從數(shù)據(jù)庫讀取出來(返回的是一個可以直接解析的option的JSON格式的數(shù)據(jù))
- 組件中使用mount掛載觸發(fā)獲取option數(shù)據(jù)
- 父組件中點擊上一條、下一條存在組件切換
- 不同組件切換時,組件確實重新加載,數(shù)據(jù)重新獲取,能夠重新渲染
問題說明:
- 同組件的多條記錄切換,組件不會動態(tài)加載,mount中不會執(zhí)行獲取option數(shù)據(jù)的方法
- 同組件多條記錄切換,Echarts中的數(shù)據(jù)會展示之前的殘留數(shù)據(jù)
- 如果返回的集合中沒有option這條記錄,那么有Echarts中的數(shù)據(jù)會渲染切換之前的數(shù)據(jù)
- 如果一個組件中渲染了兩個Echarts,當(dāng)兩個option都沒有數(shù)據(jù)時,第一個的確不會渲染,但是第二個渲染的還是切換之前的數(shù)據(jù)
解決
問題1解決
問題:
- 同組件的多條記錄切換,組件不會動態(tài)加載,mount中不會執(zhí)行獲取option數(shù)據(jù)的方法
解決:
- 父組件中,根據(jù)組件名稱動態(tài)賦值ref屬性,根據(jù)ref屬性,直接在父組件中調(diào)用加載數(shù)據(jù)的方法
<component :ref="`detail_${detailCom}`" :is="detailCom" :summaryLabel="summaryLabel" :concernDetList="concernDetailList"></component>
//頁面切換
changePage(type){
if(this.concernDetailList.length === 0){
this.detailCom = "Empty"
}else {
// 根據(jù)newVal來:1、展示對應(yīng)的組件,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"
//政策解讀 待定,頁面還未開發(fā)
//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)
}
}
},
缺陷:
- 同組件不觸發(fā)動態(tài)加載不會出問題,但是不同組件或者初次進入時,組件是動態(tài)加載的,此時ref并沒有賦值,因此瀏覽器控制臺會有一個報錯,不過不影響使用,就沒管了
問題2解決
問題:
- 同組件多條記錄切換,Echarts中的數(shù)據(jù)會展示之前的殘留數(shù)據(jù)
解決: - 這個問題很簡單,只需要在Echarts渲染option數(shù)據(jù)時,清除舊數(shù)據(jù)就可以了,一個參數(shù)就能搞定
- 原本是這么寫的:
this.myChart.setOption(option);,現(xiàn)在這么寫:this.myChart.setOption(option,true);,避免上一次渲染的緩存干擾
問題3解決
問題:
- 如果返回的集合中沒有option這條記錄,那么有Echarts中的數(shù)據(jù)會渲染切換之前的數(shù)據(jù)
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"){
//圖示區(qū)域
this.resPersonList = JSON.parse(item.columnContent2 || "[]");
this.myChart = this.$echarts.init(document.getElementById('lineEcharts'));
option = JSON.parse(item.columnContent1 || "[]");
console.log("============",option)
// 加true參數(shù),避免上一次渲染的緩存干擾
this.myChart.setOption(option,true);
//響應(yīng)屏幕寬高
window.addEventListener('resize', () => {
if (this.myChart) {
this.myChart.resize();
}
});
}
})
解決:
- 說到底還是
this.myChart.setOption(option,true);這個true的問題 - 這個問題只能在后臺處理,因為想要清空上一個Echarts中的option的話,必須要進到this.sort===2這個邏輯
- 而現(xiàn)在的問題是后臺沒有查到對應(yīng)的這條記錄時,壓根就不返回
- 因此需要在后臺去判斷有沒有sort=2的記錄,如果沒有必須寫一個空的返回出來,這樣前端才能進到這個邏輯
問題4解決
問題:
如果一個組件中渲染了兩個Echarts,當(dāng)兩個option都沒有數(shù)據(jù)時,第一個的確不會渲染,但是第二個渲染的還是切換之前的數(shù)據(jù)
解決:嘗試寫了好久的邏輯,一直都不知道還有個clear方法
反正子組件不能這么寫:
this.myChart.setOption([],true);,這么寫會報錯,直接讓第二個渲染方法不執(zhí)行,因此就不會渲染空數(shù)據(jù),也就會展示殘留的臟數(shù)據(jù)了用
this.myChart.clear()完美解決問題父組件
//頁面切換
changePage(type){
if(this.concernDetailList.length === 0){
this.detailCom = "Empty"
}else {
// 根據(jù)newVal來:1、展示對應(yīng)的組件,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"
//政策解讀 待定,頁面還未開發(fā)
//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;
//根據(jù)上一條的ID查詢對應(yīng)的詳情
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;
//根據(jù)下一條的ID查詢對應(yīng)的詳情
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)=>{
//更新關(guān)注事項詳情
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{
//圖示區(qū)域
//let option = JSON.parse(item.columnContent1 || "[]");
// 加true參數(shù),避免上一次渲染的緩存干擾
this.myChart.setOption(option,true);
//響應(yīng)屏幕寬高
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參數(shù),避免上一次渲染的緩存干擾
this.myChart2.setOption(option,true);
//響應(yīng)屏幕寬高
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渲染數(shù)據(jù)導(dǎo)致殘留臟數(shù)據(jù)的問題處理的詳細內(nèi)容,更多關(guān)于Vue Echarts渲染后殘留臟數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue實現(xiàn)將圖像文件轉(zhuǎn)換為base64
這篇文章主要介紹了vue實現(xiàn)將圖像文件轉(zhuǎn)換為base64,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02
Vue項目中new?Vue()和export?default{}的區(qū)別說明
這篇文章主要介紹了Vue項目中new?Vue()和export?default{}的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03

