Akryum / vue-virtual-scroller

⚡️ Blazing fast scrolling for any amount of data
https://vue-virtual-scroller-demo.netlify.app
9.43k stars 901 forks source link

SlotProp index of RecycleScroller is undefined #867

Open souphuhn opened 5 months ago

souphuhn commented 5 months ago

Describe the bug

Hi,

I have found a bug in the RecycleScroller. It is reproducible by my provided example.

If I re-compute my items array in <recycle-scroller :items="items">

from e.g.

[{id: '0'}, {id: '1'}, {id: '2'}]

to

[{id: '0'}, {id: '1'}, {id: '2'}, {id: '3'}, {id: '4'}, {id: '5'}]

then the index inside the slotProps {index, item, active} for the last 3 items {id: '3'}, {id: '4'}, {id: '5'} is undefined.

Another example:

If I re-compute my items from e.g.

[{id: '0'}, {id: '1'}, {id: '2'}]

to

[{id: '3'}, {id: '4'}, {id: '5'}, {id: '6'}, {id: '7'}, {id: '8'}]

then the index inside the slotProps {index, item, active} for the first items {id: '3'}, {id: '4'}, {id: '5'} is undefined.

My example works perfectly with the <dynamic-scroller>. If I use Math.random() as IDs, then my example also works with <recycle-scroller>. I have no clue...

@Akryum Did I misunderstood something? Did I use something wrong? Could you have a check?! Thanks appreciate.

Reproduction

<template>
    <recycle-scroller v-slot="{ active, item, index }" class="scroller" :items="items" :item-size="32" key-field="id">
        <div>{{ index }}{{ active }}{{ item }}</div>
    </recycle-scroller>
</template>

<script lang="ts" setup>
import { computed, ref, onMounted, nextTick } from 'vue';
// @ts-ignore No d.ts exist
import { RecycleScroller, DynamicScroller, DynamicScrollerItem } from 'vue-virtual-scroller';

const reduced = ref(false);

const items = computed((): { id: string }[] => {
    const arr: IdentifiableItem[] = [];

    if (reduced.value) {
        for (let i = 0; i < 3; i += 1) {
            arr.push({ id: `${i}` });
        }
    } else {
        for (let i = 0; i < 6; i += 1) {
            arr.push({ id: `${i}` });
        }
    }

    return arr;
});

onMounted(async () => {
    await nextTick();
    reduced.value = true;
    await nextTick();
    reduced.value = false;
});
</script>

<style lang="scss" scoped>
.scroller {
    width: 100%;
    height: 100%;
}
</style>

System Info

"vue": "3.3.7",
"scroller": v2.0.0-beta.8,

Used Package Manager

npm

Validations

souphuhn commented 5 months ago

Ok it is related to https://github.com/Akryum/vue-virtual-scroller/pull/784