Vue JS 在渲染前等待数据
[英] Vue JS waiting for data before rendering
本文介绍了Vue JS 在渲染前等待数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
几周以来,我一直在使用 VueJS 渲染数据时遇到问题.
我正在做的是进行一些 axios 调用(一个在另一个内部).我的问题是数据在调用完成之前呈现,因此视图没有显示任何内容.
我看到了一些执行等待"的代码和异步调用"但似乎没有什么能解决我的问题.
这里也有类似的东西获取组件在渲染前等待异步数据但也不行
这是我的代码:
<div class="m-portlet m-portlet--full-height";m-portlet=真"id=m_portlet_validate_agenda">...<div class="m-portlet__body"><div class="tab-content"><div class="tab-pane active"id=m_widget2_tab1_diagnose"><div class="m-widget2"><div v-for=诊断中的诊断";v-if=diagnoses.length";:class="'m-widget2__item m-widget2__item--'+diagnos.delayColor[0]"><div class="m-widget2__checkbox";><label class="m-checkbox m-checkbox--solid m-checkbox--single m-checkbox--brand"><span class="m--bg-white";v-html=diagnose.concurrence"></span>标签>
<div class="m-widget2__agenda col-2">{{ 诊断.started_at |时刻(HH:mm A")}}
<div class="m-widget2__desc";v-if="!isFetching"><div><span class="m-widget2__text"></span><br><span class="m-widget2__user-name"><a href="#";class="m-widget2__link m-link">帕切特:{{诊断.详细信息[0].名称}}</a><br><a href="#";class="m-widget2__link m-link">特拉坦特:</a></span>
模板><脚本>导出默认{数据() {返回 {事件:[],诊断:[],紧急情况:[],治疗:[],isFetching: 真}},安装(){this.loadData();},方法: {加载数据:异步函数(){await axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos').then(res => {this.events = res.data;this.diagnoses = [];this.urgencies = [];this.treatments = [];this.getDetails();this.getDelayColor();this.getConcurrence();vm.$nextTick(function () {$('[data-toggle="m-tooltip"]').tooltip();});console.log('end LoadData');});},获取详细信息:函数(){console.log('cargando');this.events.forEach(event => {axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos/' + event.id).then(res => {event.details = res.data;控制台日志(res.data);});});this.distributeEvents();console.log('montado');},分发事件:函数(){this.events.forEach(event => {if ( event.event.event_type == "诊断" ){this.diagnoses.push(event);}else if ( event.event.event_type == "urgency" ){this.urgencies.push(event);}else if ( event.event.event_type == "treatment"){this.treatments.push(event);}});this.isFetching = false;},获取延迟颜色:函数(){this.events.forEach(event => {做一点事...});},获取并发:函数(){this.events.forEach(event => {做一点事...});},diffMinutes:函数(started_at){做一点事...}}}
解决方案
您没有正确处理 Promise,因此它们不断未解决.您可以使用 async
、await
,尽管我更喜欢使用普通的 Promise 对象:
getDetails()
是另一回事.您正在制作一个循环,并且 forEach
循环您正在发送一个 axios 请求.您可能必须将每个 axios 调用返回的每个 Promise 存储在一个数组中,然后调用 Promise.all.
getDetails: function() {让 url = '/pacientes/request-json/agenda/validarAsistencia/eventos/';console.log('加载');让承诺的事件 = [];this.events.forEach(event => {promiseEvents.push(axios.get(url + event.id))});返回 Promise.all(promisedEvents)},
之后我会做这样的事情:
loadData: function() {axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos').then(res => {this.events = res.data;this.getDelayColor()//同步操作;无需退货返回 this.getDetails();//返回承诺}).then((res) => {//对来自 Promise 数组的响应做一些事情}).then(anotherPromise)//你也可以像这样返回一个promise.catch(handleError)//处理错误非常重要!!});},
我并不是说这是实现您可能想要的最佳方式,而是说这是使您的代码工作的一种方式.这里重要的是你需要了解 Promises.
I'm stuck since a few weeks in a problem with rendering data with VueJS.
What I'm doing is making some axios calls (one inside another). My problem is that the data is rendered before the calls has completed, so the view is not showing anything.
I saw some codes that do some "await" and "Async calls" but nothing seems to solve my problem.
Also there is something similar here
Get component to wait for asynchronous data before rendering
But isn't working either
here is my code:
<template>
<div class="m-portlet m-portlet--full-height" m-portlet="true" id="m_portlet_validate_agenda">
...
<div class="m-portlet__body">
<div class="tab-content">
<div class="tab-pane active" id="m_widget2_tab1_diagnose">
<div class="m-widget2">
<div v-for="diagnose in diagnoses" v-if="diagnoses.length" :class="'m-widget2__item m-widget2__item--' + diagnose.delayColor[0]">
<div class="m-widget2__checkbox" >
<label class="m-checkbox m-checkbox--solid m-checkbox--single m-checkbox--brand">
<span class="m--bg-white" v-html="diagnose.concurrence"></span>
</label>
</div>
<div class="m-widget2__agenda col-2">
{{ diagnose.started_at | moment("HH:mm A") }}
</div>
<div class="m-widget2__desc" v-if="!isFetching">
<div>
<span class="m-widget2__text">
</span><br>
<span class="m-widget2__user-name">
<a href="#" class="m-widget2__link m-link">
Paciente:
{{ diagnose.details[0].name }}
</a><br>
<a href="#" class="m-widget2__link m-link">
Tratante:
</a>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
events: [],
diagnoses: [],
urgencies: [],
treatments: [],
isFetching: true
}
},
mounted() {
this.loadData();
},
methods: {
loadData: async function() {
await axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos').then(res => {
this.events = res.data;
this.diagnoses = [];
this.urgencies = [];
this.treatments = [];
this.getDetails();
this.getDelayColor();
this.getConcurrence();
vm.$nextTick(function () {
$('[data-toggle="m-tooltip"]').tooltip();
});
console.log('end LoadData');
});
},
getDetails: function() {
console.log('cargando');
this.events.forEach(event => {
axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos/' + event.id).then(res => {
event.details = res.data;
console.log(res.data);
});
});
this.distributeEvents();
console.log('montado');
},
distributeEvents: function() {
this.events.forEach(event => {
if ( event.event.event_type == "diagnosis" )
{
this.diagnoses.push(event);
}
else if ( event.event.event_type == "urgency" )
{
this.urgencies.push(event);
}
else if ( event.event.event_type == "treatment" )
{
this.treatments.push(event);
}
});
this.isFetching = false;
},
getDelayColor: function() {
this.events.forEach(event => {
do something...
});
},
getConcurrence: function() {
this.events.forEach(event => {
do something...
});
},
diffMinutes: function(started_at) {
do something...
}
}
}
解决方案
You aren't handling Promises properly, so they keep getting unresolved. You can use async
, await
, although I prefer myself using plain Promise Objects:
getDetails()
is another story. You are making a loop, and forEach
loop you are sending an axios request. You could have to store each Promise returned by each axios call in an array, to call then Promise.all.
getDetails: function() {
let url = '/pacientes/request-json/agenda/validarAsistencia/eventos/';
console.log('loading');
let promisedEvents = [];
this.events.forEach(event => {
promisedEvents.push(axios.get(url + event.id))
});
return Promise.all(promisedEvents)
},
After that I would do something like this:
loadData: function() {
axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos')
.then(res => {
this.events = res.data;
this.getDelayColor() // sync operation; no need to be returned
return this.getDetails(); // Return the promise(s)
})
.then((res) => {
// do something with the response from your array of Promises
})
.then(anotherPromise) // You can also return a promise like this
.catch(handleError) // Very important to handle your error!!
});
},
I am not saying this is the best way to achieve what you may want, but that it is one way to make your code to work. Important here is that you need to learn about Promises.
这篇关于Vue JS 在渲染前等待数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文