В проекте Nuxt.js у меня есть страница, на которой мне нужно выполнить некоторые вычисления на стороне клиента, прежде чем некоторые данные будут отображены в таблице.
До и во время расчета хочу показать экран загрузки.
Некоторый контекст: данные представляют собой графики, используемые фермером. Таблица должна показать, какой урожай был выращен на участке в последние годы.
Данные хранятся в базе данных следующим образом:
plots = [{
name: 'Plot1',
year: 2017,
crop: 'Wheat'
...
}, {
name: 'Plot1',
year: 2018,
crop: 'Maize',
...
} ...]
В методе данные преобразуются во вложенный объект следующей структуры
data = {
'Plot1': {
2017: {
'crop': 'Wheat',
'catchCrop': true
},
2018: {
'crop': 'Maize',
'catchCrop': false
}
}
...
}
и впоследствии отображается в компоненте таблицы.
Макет компонента выглядит следующим образом:
<template>
<loadingComponent v-if="loading"/>
<tableComponent v-else-if="!loading && dataAvailable"/>
<span v-else >No data</span>
</template>
<script>
data() {
return {
loading: true,
dataAvailable: false
}
},
mounted() {
this.startCalculation()
},
methods: {
startCalculation() {
if (store.data) {
// long running calculation, then
this.dataAvailable = true
}
this.loading = false
}
}
</script>
Проблема, с которой я сталкиваюсь, заключается в том, что компонент загрузки никогда не отображается.
Однако метод startCalculation
блокирует интерфейс пользователя (что было бы нормально, если бы отображался загружаемый компонент), и компонент обновляется только ПОСЛЕ завершения расчета.
Кто-нибудь имеет представление о том, как я мог бы обойти это?
Большое спасибо заранее!
EDIT:
Поиграв, я мог заставить его работать так, как я хочу, установив setTimeout
в 1 мс. Таким образом, отображается индикатор загрузки, данные обрабатываются правильно, а затем индикатор загрузки удаляется после завершения расчета. Тем не менее, это похоже на очень грязный хак, и я хотел бы избежать этого ...
mounted() {
this.loading = true
// set short timeout in order for Vue to render the loading bar
setTimeout(() => {
this.startCalculation()
this.loading = false
},1)
}