Reputation: 15934
I have a calendar type page in my app which has to calculate the appointments due on that day. This operation only takes about 35ms per day but when you're looking at a month, it adds up. Currently, as I am looping through my dates, nothing is rendered until ALL the days have been loaded.
I thought I'd try and get a simpler example to test with so:
<span v-for="n in 100000000">{{ n }} </span>
Even doing something as simple as this, the span won't render until it's been through all 100 million iterations.
How can I get this to render 1 then 2, then 3 etc rather than rendering when it's completed the loop?
Edit: This is my real world example:
<planner-day
v-for="date in getDates(index, index + selectedFilters.daysPerRow)"
v-if="plannerStartDate"
:date="date"
:timeDisplayType="selectedFilters.timeDisplayType"
:timeInterval="selectedFilters.timeInterval"
:jobs="items"
:filteredDateRange="selectedFilters.dateRange"
:jobDueDates="jobDueDates"
:roundJobCounts="roundJobCounts"
></planner-day>
index
above is from an outer loop. This is getDates()
:
getDates (rowIndex) {
let rangeStart = parseInt(rowIndex) * parseInt(this.selectedFilters.daysPerRow)
let rangeEnd = rangeStart + parseInt(this.selectedFilters.daysPerRow)
let dates = []
let currentRow = 0
var currentDate = this.selectedFilters.dateRange.start.clone().subtract(1, 'days')
while (currentDate.add(1, 'days').diff(this.selectedFilters.dateRange.end) <= 0 && currentRow < rangeEnd) {
if (currentRow >= rangeStart) {
dates.push(currentDate.clone().startOf('day'))
}
currentRow++
}
return dates
}
Upvotes: 0
Views: 99
Reputation: 31362
You can try this using a directive like this:
<outer-loop v-for="(item, index) in myArray" v-getDates="index">
<planner-day v-for="date in myDates"></<planner-day>
</outer-loop>
In the component script
data(){
return{
myDates:[]
};
},
directive:{
getDates: {
bind(el, binding, Vnode){
var vm = Vnode.context;
var index = binding.value;
let rangeStart = parseInt(index) * parseInt(vm.selectedFilters.daysPerRow)
let rangeEnd = rangeStart + parseInt(vm.selectedFilters.daysPerRow)
let currentRow = 0
var currentDate = vm.selectedFilters.dateRange.start.clone().subtract(1, 'days')
var myLoop = function(i){
if (i >= rangeStart) {
vm.myDates.push(currentDate.clone().startOf('day'));
}
if(currentDate.add(1, 'days').diff(vm.selectedFilters.dateRange.end) <= 0 && i < rangeEnd){
i++;
myLoop(i);
}
}
myLoop(currentRow);
}
}
}
The loop will be adding items to myDates[ ]
array. Since myDates[ ]
is initialized in data option it is reactive and you can loop through it.
Here is the example fiddle.
Upvotes: 1