Vue JS 在渲染之前等待数据
2019-01-03
62302
几周以来,我一直被 VueJS 渲染数据的问题所困扰。
我正在做的是进行一些 axios 调用(一个在另一个里面)。我的问题是数据在调用完成之前就被渲染了,所以视图没有显示任何内容。
我看到了一些执行“await”和“Async 调用”的代码,但似乎没有什么能解决我的问题。
这里也有类似的东西 获取组件在渲染之前等待异步数据 但也没有用
这是我的代码:
<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...
}
}
}
3个回答
为了防止组件在数据返回之前进行渲染,您可以:
-
向数据添加“isFetching”属性并将其设置为“true”
-
在获取回调中,将 isFetching 设置为“false”
3.将 v-if="!isFetching" 添加到组件的包装器
Adi Darachi
2019-01-03
您没有正确处理 Promises,因此它们一直处于
未解决
状态。您可以使用
async
、
await
,尽管我更喜欢使用普通的
Promise 对象
:
getDetails()
是另一回事。您正在创建一个循环,并且
forEach
循环正在发送一个
axios
请求。您可能必须将每个
axios
调用返回的每个
Promise
存储在一个数组中,然后调用
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)
},
之后,我会做这样的事情:
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!!
});
},
我并不是说这是实现您想要的最佳方式,但它是让您的代码正常工作的一种方法。这里重要的是您需要了解 Promises。
nicoramirezdev
2019-01-03
解决方案:
谢谢大家!
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
this.getConcurrence();
vm.$nextTick(function () {
$('[data-toggle="m-tooltip"]').tooltip();
});
return this.getDetails(); // Return the promise(s)
})
.then((res) => {
console.log(res.length);
for (var i = 0; i < res.length; i++) {
this.events[i].details = res[i].data;
}
this.distributeEvents();
console.log('end LoadData');
})
.catch(error => {
console.log('error');
})
},
getDetails: function() {
let url = '/pacientes/request-json/agenda/validarAsistencia/eventos/';
let promisedEvents = [];
this.events.forEach(event => {
promisedEvents.push(axios.get(url + event.id))
});
return Promise.all(promisedEvents)
},
Pablo Araya
2019-01-03