I have a Vuetify v-data-table with about a 1000 rows in it. Rendering it for the first time and when text searching on it, the render takes a few seconds. During this time I want to overlay it with a scrim + spinner to indicate things are happening.
The overlay:
<v-overlay
:value="loading"
opacity="0.7"
absolute
v-mutate="onMutate"
>
<v-progress-circular indeterminate size="32" color="blue"></v-progress-circular>
</v-overlay>
The v-data-table:
<v-data-table
:headers="cHeaders"
:items="cLimitedData"
disable-pagination
hide-default-footer
:search="searchIntercepted"
@current-items="tstCurrentItems"
>
The computed variable cLimitedData
:
cLimitedData() {
if (this.indNoLimit) {
return this.data
} else {
return this.data.slice(0,this.dtRowTo)
}
},
I watch the search
variable, and when it changes, I set loading
to true to activate the overlay.
watch: {
search() {
if (!this.indNoLimit) {
// remove limit, this will cause cLimitedData to return all rows
this.loading = true
// -> moved to onMutate
//this.$nextTick(function () {
// this.indNoLimit = true
//})
} else {
this.searchIntercepted = this.search
}
},
However, the overlay doesn't activate until after the v-data-table had finished rendering. I've tried a million things, one of them is to put a v-mutate="onMutate"
on the overlay, and only when it fired, would I this.indNoLimit = true
to set things in motion, but that is still not good enough to have the scrim start before the v-data-table begins reloading itself.
onMutate(thing1) {
console.log('@onMutate',thing1)
this.$nextTick(function () {
this.indNoLimit = true
this.searchIntercepted = this.search
})
},
I also found that the next tick in @current-items fairly reliably marked the end of the render of the v-data-table, thus the deactivation of the scrim is probably going to be ok:
tstCurrentItems(thing1) {
console.log('@current-items',thing1)
this.$nextTick(function () {
console.log('@current-items NEXT')
this.loading = false
})
I believe my question should be: how can I detect/wait for components to have rendered (the v-overlay+v-progress-circular) before making changes to other components (the v-data-table).
Note: To solve the initial wait time of loading of the table, I found a way to progressively load it by inserting div-markers that trigger a v-intersect. However, this does not solve the situation when a user searches the whole data set when only the first 50 rows are loaded.
EDIT: Tried to start the update of the table after the overlay has been activated using https://github.com/twickstrom/vue-force-next-tick, but still no luck. It almost looks like vue tries to aggregate changes to the DOM instead of executing them one by one.