我有一个Vuetify v-data-table,其中有大约1000行。第一次渲染它,当在其上搜索文本时,渲染过程需要几秒钟。在这段时间里,我想用稀松布+微调器覆盖它,以指示事情正在发生。
叠加层:
<v-overlay
:value="loading"
opacity="0.7"
absolute
v-mutate="onMutate"
>
<v-progress-circular indeterminate size="32" color="blue"></v-progress-circular>
</v-overlay>
v-data-table:
<v-data-table
:headers="cHeaders"
:items="cLimitedData"
disable-pagination
hide-default-footer
:search="searchIntercepted"
@current-items="tstCurrentItems"
>
计算出的变量cLimitedData
:
cLimitedData() {
if (this.indNoLimit) {
return this.data
} else {
return this.data.slice(0,this.dtRowTo)
}
},
我观看了search
变量,当它改变时,我将loading
设置为true以激活覆盖。
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
}
},
但是,只有在v-data-table完成渲染后,覆盖层才会激活。我已经尝试了一百万种东西,其中之一是将v-mutate="onMutate"
放在叠加层上,只有当它被发射时,我this.indNoLimit = true
才能使东西运动,但这仍然不够好在v-data-table开始重新加载自身之前先启动scrim。
onMutate(thing1) {
console.log('@onMutate',thing1)
this.$nextTick(function () {
this.indNoLimit = true
this.searchIntercepted = this.search
})
},
我还发现@ current-items中的下一个滴答声相当可靠地标记了v-data-table的渲染结束,因此取消稀松布可能是可以的:
tstCurrentItems(thing1) {
console.log('@current-items',thing1)
this.$nextTick(function () {
console.log('@current-items NEXT')
this.loading = false
})
我相信我的问题应该是:在更改其他组件(v-data-table)之前,如何检测/等待组件已呈现(v-overlay + v-progress-circular)
。注意:为了解决表加载的初始等待时间,我找到了一种方法,可以通过插入触发v交叉的div标记逐步加载它。但是,当用户仅加载前50行时搜索整个数据集时,这并不能解决这种情况。
编辑:尝试使用https://github.com/twickstrom/vue-force-next-tick激活叠加层后开始表的更新,但是仍然没有运气。似乎vue试图将更改汇总到DOM,而不是一一执行。
答案 0 :(得分:0)
我还没有弄清楚为什么v-data-table似乎会阻塞/冻结,但是这里有一个可以简化任何大型v-data-table的解决方案:
v数据表:
[Test]
public async Task AutoRefresh()
{
var key = "someKey";
var refreshInterval = TimeSpan.FromSeconds(1);
var timesGenerated = 0;
// this is the Func what we are caching
ComplexTestObject GetStuff()
{
timesGenerated++;
return new ComplexTestObject();
}
// this sets up options that will recreate the entry on eviction
MemoryCacheEntryOptions GetOptions()
{
var options = new LazyCacheEntryOptions()
.SetAbsoluteExpiration(refreshInterval, ExpirationMode.ImmediateExpiration);
options.RegisterPostEvictionCallback((keyEvicted, value, reason, state) =>
{
if (reason == EvictionReason.Expired || reason == EvictionReason.TokenExpired)
sut.GetOrAdd(key, _ => GetStuff(), GetOptions());
});
return options;
}
// get from the cache every 2s
for (var i = 0; i < 3; i++)
{
var thing = sut.GetOrAdd(key, () => GetStuff(), GetOptions());
Assert.That(thing, Is.Not.Null);
await Task.Delay(2 * refreshInterval);
}
// we refreshed every second in 6 seconds so generated 6 times
// even though we only fetched it every other second which would be 3 times
Assert.That(timesGenerated, Is.EqualTo(6));
}
添加div或任何其他元素以给定的间隔相交。每次与它相交时,我们都会增加页面大小。
变量:
<v-data-table
:headers="cHeaders"
:items="data"
:items-per-page="dtRowTo"
hide-default-footer
hide-default-header
:search="search"
item-key="id"
>
<template
v-slot:item="{item, index, isSelected, select, headers}"
>
<tr>
<td
:colspan="headers.length"
>
Stuff
<div v-if="(index+1)%25==0" v-intersect.quiet.once="onIntersect">{{index+1}}</div>
</td>
</tr>
</template>
</v-data-table>
onIntersect :
dtRowTo: 50, // initial nr of rows
dtRowIncr: 50, // increments
不幸的是,您无法将索引添加为 onIntersect (entries, observer) {
let index = entries[0].target.textContent
if (index == this.dtRowTo) {
this.dtRowTo += this.dtRowIncr
}
},
之类的参数,因为它会在与函数相交之前执行该函数(不确定原因),因此我们必须将索引从textContext中删除。
基本上,您要做的是每次在页面底部时都增加页面大小。搜索仍将在整个数据集上进行。
不的工作原理(我发现很难)是逐步增加项目,例如下面的计算函数。由于搜索需要将整个数据集都显示在:items上,因此将无法使用:
v-intersect.quiet.once="onIntersect(index)"
只要您不需要搜索或对整个数据集有效的任何操作,这样做就很好(我想?)。