Akryum / vue-virtual-scroller

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

Items overlap #828

Open simionato-mobisec opened 1 year ago

simionato-mobisec commented 1 year ago

Describe the bug

I followed what is written here to implement a dynamic scroller, but looks like the items overlap.

Reproduction

MyDynamicScroller.vue

<template>
  <DynamicScroller
    style="height: 500px;"
    :items="items"
    :min-item-size="24"
  >
    <template #default="{ item, index, active }">
      <DynamicScrollerItem
        :item="item"
        :active="active"
        :size-dependencies="[item]"
        :data-index="index"
      >
        {{ `${index} ${item}` }}
      </DynamicScrollerItem>
    </template>
  </DynamicScroller>
</template>

<script>
export default {

  data() {
    return {
      items: []
    }
  },

  created() {
    this.findMessages()
  },

  methods: {

    findMessages() {
      MessageService.findAll().then(
        ({ data }) => {
          this.items = data
        },
        err => {
          console.log(err)
        }
      )
    }
  }
}
</script>

Messages have variable heights, with a min height of 24px. This is the output: scroller As you can see, items are overlapped (don't pay attention to weird chars).

Used Package Manager

npm

Validations

vsambor commented 4 months ago

I had the same issue with the RecycleScroller, when the list changes sometimes (especially the first time, but not only) the items would overlap. And as a workaround I found that you have to recreate the entire component. This is how I did it.

const shouldUpdateScroller = ref(true);

// When my list data updates
watch(list, () => {
    // Force scroller to refresh;
    shouldUpdateScroller.value = false;
    nextTick(() => {
        shouldUpdateScroller.value = true;
    });
});

// Then in the template

<RecycleScroller
                v-if="list.length > 0 && shouldUpdateScroller"
                ...
 />

It's sad the lib is not maintained anymore :(

Last-Dance-W commented 2 months ago

I have also encountered such a problem ,Has it been resolved?

CatherineAugustine commented 2 months ago

Same issue here . Any solution?

CatherineAugustine commented 2 months ago

I had the same issue with the RecycleScroller, when the list changes sometimes (especially the first time, but not only) the items would overlap. And as a workaround I found that you have to recreate the entire component. This is how I did it.

const shouldUpdateScroller = ref(true);

// When my list data updates
watch(list, () => {
    // Force scroller to refresh;
    shouldUpdateScroller.value = false;
    nextTick(() => {
        shouldUpdateScroller.value = true;
    });
});

// Then in the template

<RecycleScroller
                v-if="list.length > 0 && shouldUpdateScroller"
                ...
 />

It's sad the lib is not maintained anymore :(

This didnt help me

vsambor commented 2 months ago

@CatherineAugustine what do you experience? I'm surprised the workaround didn't help. (can you share some of your code?)

CatherineAugustine commented 2 months ago

@CatherineAugustine what do you experience? I'm surprised the workaround didn't help. (can you share some of your code?)

<RecycleScroller
          v-if="results && results.length > 0 && shouldUpdateScroller"
           :emit-update="true"
            page-mode
            :items="results"
            item-height="10"
            key-field="item"
            :item-size="5" :min-item-height="5"
            class="scroller"
            v-slot="{ item }"
          >
            <li  >
              {{  item  }}
            </li>
          </RecycleScroller>

My results are an array of string ['11111111','222222','33333333'] of upto 380k records

vsambor commented 2 months ago

@CatherineAugustine Try to do this first to see if it works:

<RecycleScroller
  v-if="results && results.length > 0 && shouldUpdateScroller"
    class="scroller"
    :items="results"
    :item-size="5" 
    v-slot="{ item, index }"
  >
    <li  >
      {{  item  }} {{ index }}
    </li>
</RecycleScroller>

Note you will have to modify your items to contain an id like items = [{id:0, text: '111111'}, {id:1, text: '22222'} ...]

If this works then try to add :page-mode="true" and other things.

Note: by default the key-field is id so no need to specify

Also probably you have to much height props, for me just setting the item-size was enough.

Good luck and let me know if it works for you.

CatherineAugustine commented 2 months ago

Sadly, adding the id didn't help.

One thing I noticed is that, if I remove the v-if="results && results.length > 0 && shouldUpdateScroller" condition, the overlapping is gone, but the dropdown doesn't repaint when the results are modified, though I have declared the results field reactive.

I am using "vue-virtual-scroller": "^2.0.0-beta.8" on Vue3.

CatherineAugustine commented 2 months ago
.vue-recycle-scroller.ready .vue-recycle-scroller__item-view {
   position: absolute;
}

This style is causing the items to overlap.

vsambor commented 2 months ago

I would like to see your example, to try it more. Could you create a reproducible example like in stackblitz or somewhere? I have the same version as you "vue-virtual-scroller": "^2.0.0-beta.8" and It works for me.

CatherineAugustine commented 2 months ago

:item-size="5"

property needs to be looked into for overlapping values. I changed it to 30 and it worked fine .

vsambor commented 2 months ago

Happy it works for you, I didn't pay attention that you used 5 px :) All the best!