VueJS methods与生命周期问题:retrieveTutorials无法赋值数据给baseDeDatosVias
问题根因
你遇到的是JavaScript异步执行顺序问题:retrieveTutorials 方法中调用的 TutorialDataService.get 是网络异步请求,调用后不会阻塞后续代码执行。你在 populateGrados 里调用完 retrieveTutorials 后立刻读取 this.baseDeDatosVias 时,请求还未返回响应,this.baseDeDatosVias 还是初始的空数组,因此无法拿到数据。
修复方案
用 async/await 调整异步逻辑的执行顺序:
- 先修改
retrieveTutorials方法,让它返回Promise对象:
async retrieveTutorials() { try { const response = await TutorialDataService.get(this.$auth.user.name) this.baseDeDatosVias = response.data; console.log(this.baseDeDatosVias); } catch (e) { console.log(e); } }
- 把
populateGrados改为异步方法,等待请求完成后再处理数据,同时把cantidadDeEncadenadas的赋值逻辑移到数据处理完成后执行:
async populateGrados() { // 等待请求返回数据后再执行后续逻辑 await this.retrieveTutorials(); this.cantViasEncadadenasPorGrados= []; const keys = Object.keys(this.baseDeDatosVias); console.log(keys); keys.forEach((key, index) => { if ((`${this.baseDeDatosVias[key].encadenada}`) === "false"){ return } const grado = `${this.baseDeDatosVias[key].grado}` if (grado === "5"){ this.dataParaViasEncadenadas.quinto++; } else if(grado === "5+"){ this.dataParaViasEncadenadas.quintoMas++; } else if(grado === "6a"){ this.dataParaViasEncadenadas.sextoA++; } else if(grado === "6a+"){ this.dataParaViasEncadenadas.sextoAMas++; } else if(grado === "6b"){ this.dataParaViasEncadenadas.sextoB++; } else if(grado === "6b+"){ this.dataParaViasEncadenadas.sextoBMas++; } else if(grado === "6c"){ this.dataParaViasEncadenadas.sextoC++; } else if(grado === "6c+"){ this.dataParaViasEncadenadas.sextoCMas++; } else if(grado === "7a"){ this.dataParaViasEncadenadas.septimoA++; } else if(grado === "7a+"){ this.dataParaViasEncadenadas.septimoAMas++; } else if(grado === "7b"){ this.dataParaViasEncadenadas.septimoB++; } else if(grado === "7b+"){ this.dataParaViasEncadenadas.septimoBMas++; } else if(grado === "7c"){ this.dataParaViasEncadenadas.septimoC++; } else if(grado == "7c+"){ this.dataParaViasEncadenadas.septimoCMas++; } }); let claves = Object.keys(this.dataParaViasEncadenadas); for (let i=0; i<claves.length; i++){ let clave = claves[i]; this.cantViasEncadadenasPorGrados.push(this.dataParaViasEncadenadas[clave]); } // 数据处理完成后再初始化图表配置 this.cantidadDeEncadenadas= { labels: ["5", "5+", "6a" ,"6a+", "6b", "6b+", "6c", "6c+", "7a", "7a+", "7b", "7b+", "7c","7c+"], datasets: [ { label: "Vias.", borderColor: '#fcc468', fill: true, backgroundColor: '#fcc468', hoverBorderColor: '#fcc468', borderWidth: 4, data: this.cantViasEncadadenasPorGrados, }, ] }; }
- 修改mounted钩子,调用异步的populateGrados:
mounted(){ this.populateGrados(); }
额外优化建议
- 如果你后端返回的
response.data是对象类型,建议把baseDeDatosVias的初始值从[]改为{},避免Object.keys处理空数组时出现异常 - 长串的else if可以用映射表简化:先定义一个grado和属性名的映射对象
const gradoMap = {'5':'quinto','5+':'quintoMas', ...},遍历的时候直接取值赋值即可,不用写大量判断 - 你代码里
statsCards配置项里有笔误,最后一个项多写了一个type属性:type type: 'info',改为type: 'info'即可
内容的提问来源于stack exchange,提问作者Maxi Gattari
相关产品推荐
相关产品推荐

