Vuetify:如何在v-data-table渲染时显示微调器的叠加(如何等待组件完成渲染)

时间:2020-09-20 11:16:45

标签: vuejs2 vuetify.js

我有一个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,而不是一一执行。

1 个答案:

答案 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)"

只要您不需要搜索或对整个数据集有效的任何操作,这样做就很好(我想?)。

相关问题