⚡️ Blazing fast scrolling for any amount of data

Overview

vue-virtual-scroller

npm npm vue2

Blazing fast scrolling of any amount of data | Live demo | Video demo

Become a Patreon

Sponsors

sponsors logos

Table of contents

Installation

npm install --save vue-virtual-scroller

⚠️ vue-virtual-scroller now uses vue-observe-visibility to automatically refresh itself when shown to prevent display glitches. This means you need to include the Intersection Observer polyfill needed by vue-observe-visibility for this to work in old browsers (like Internet Explorer).

Default import

Install all the components:

import Vue from 'vue'
import VueVirtualScroller from 'vue-virtual-scroller'

Vue.use(VueVirtualScroller)

Use specific components:

import Vue from 'vue'
import { RecycleScroller } from 'vue-virtual-scroller'

Vue.component('RecycleScroller', RecycleScroller)

⚠️ The line below should be included when importing the package:

import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'

Browser

<link rel="stylesheet" href="vue-virtual-scroller/dist/vue-virtual-scroller.css"/>

<script src="vue.js"></script>
<script src="vue-virtual-scroller/dist/vue-virtual-scroller.min.js"></script>

If Vue is detected, the plugin will be installed automatically. If not, install the component:

Vue.use(VueVirtualScroller)

Or register it with a custom name:

Vue.component('RecycleScroller', VueVirtualScroller.RecycleScroller)

Usage

There are several components provided by vue-virtual-scroller:

RecycleScroller is a component that only renders the visible items in your list. It also re-uses components and dom elements to be as efficient and performant as possible.

DynamicScroller is a component that wraps the RecycleScroller component and extends its features to include dynamic size management. The main use case for this is when you do not know the size of the items in advance. The Dynamic Scroller automatically "discovers" item dimensions as it renders new items during scrolling.

DynamicScrollerItem must wrap each item in a DynamicScroller to handle size computations.

IdState is a mixin that ease the local state management in reused components inside a RecycleScroller.

RecycleScroller

RecycleScroller is a virtual scroller that only renders the visible items. As the user scrolls, RecycleScroller reuses all components and DOM nodes to maintain optimal performance.

Basic usage

Use the scoped slot to render each item in the list:

<template>
  <RecycleScroller
    class="scroller"
    :items="list"
    :item-size="32"
    key-field="id"
    v-slot="{ item }"
  >
    <div class="user">
      {{ item.name }}
    </div>
  </RecycleScroller>
</template>

<script>
export default {
  props: {
    list: Array,
  },
}
</script>

<style scoped>
.scroller {
  height: 100%;
}

.user {
  height: 32%;
  padding: 0 12px;
  display: flex;
  align-items: center;
}
</style>

Important notes

  • ⚠️ You need to set the size of the virtual-scroller element and the items elements (for example, with CSS). Unless you are using variable size mode, all items should have the same height (or width in horizontal mode) to prevent display glitches.
  • ⚠️ If the items are objects, the scroller needs to be able to identify them. By default it will look for an id field on the items. This can be configured with the keyField prop if you are using another field name.
  • It is not recommended to use functional components inside RecycleScroller since the components are reused (so it will actually be slower).
  • The list item components must be reactive to the item prop being updated without being re-created (use computed props or watchers to properly react to props changes!).
  • You don't need to set key on list content (but you should on all nested <img> elements to prevent load glitches).
  • The browsers have a size limitation on DOM elements, it means that currently the virtual scroller can't display more than ~500k items depending on the browser.
  • Since DOM elements are reused for items, it's recommended to define hover styles using the provided hover class instead of the :hover state selector (e.g. .vue-recycle-scroller__item-view.hover or .hover .some-element-inside-the-item-view).

How does it work?

  • The RecycleScroller creates pools of views to render visible items to the user.
  • A view holds a rendered item, and is reused inside its pool.
  • For each type of item, a new pool is created so that the same components (and DOM trees) are reused for the same type.
  • Views can be deactivated if they go off-screen, and can be reused anytime for a newly visible item.

Here is what the internals of RecycleScroller look like in vertical mode:

<RecycleScroller>
  <!-- Wrapper element with a pre-calculated total height -->
  <wrapper
    :style="{ height: computedTotalHeight + 'px' }"
  >
    <!-- Each view is translated to the computed position -->
    <view
      v-for="view of pool"
      :style="{ transform: 'translateY(' + view.computedTop + 'px)' }"
    >
      <!-- Your elements will be rendered here -->
      <slot
        :item="view.item"
        :index="view.nr.index"
        :active="view.nr.used"
      />
    </view>
  </wrapper>
</RecycleScroller>

When the user scrolls inside RecycleScroller, the views are mostly just moved around to fill the new visible space, and the default slot properties updated. That way we get the minimum amount of components/elements creation and destruction and we use the full power of Vue virtual-dom diff algorithm to optimize DOM operations!

Props

  • items: list of items you want to display in the scroller.
  • direction (default: 'vertical'): scrolling direction, either 'vertical' or 'horizontal'.
  • itemSize (default: null): display height (or width in horizontal mode) of the items in pixels used to calculate the scroll size and position. If it is set to null (the default value), it will use variable size mode.
  • minItemSize: minimum size used if the height (or width in horizontal mode) of a item is unknown.
  • sizeField (default: 'size'): field used to get the item's size in variable size mode.
  • typeField (default: 'type'): field used to differentiate different kinds of components in the list. For each distinct type, a pool of recycled items will be created.
  • keyField (default: 'id'): field used to identify items and optimize managing rendered views.
  • pageMode (default: false): enable Page mode.
  • prerender (default: 0): render a fixed number of items for Server-Side Rendering (SSR).
  • buffer (default: 200): amount of pixel to add to edges of the scrolling visible area to start rendering items further away.
  • emitUpdate (default: false): emit a 'update' event each time the virtual scroller content is updated (can impact performance).

Events

  • resize: emitted when the size of the scroller changes.
  • visible: emitted when the scroller considers itself to be visible in the page.
  • hidden: emitted when the scroller is hidden in the page.
  • update (startIndex, endIndex): emitted each time the views are updated, only if emitUpdate prop is true

Default scoped slot props

  • item: item being rendered in a view.
  • index: reflects each item's position in the items array
  • active: whether or not the view is active. An active view is considered visible and being positioned by RecycleScroller. An inactive view is not considered visible and is hidden from the user. Any rendering-related computations should be skipped if the view is inactive.

Other Slots

<main>
  <slot name="before"></slot>
  <wrapper>
    <!-- Reused view pools here -->
  </wrapper>
  <slot name="after"></slot>
</main>

Example:

<RecycleScroller
  class="scroller"
  :items="list"
  :item-size="32"
>
  <template #before>
    Hey! I'm a message displayed before the items!
  </template>

  <template v-slot="{ item }">
    <div class="user">
      {{ item.name }}
    </div>
  </template>
</RecycleScroller>

Page mode

The page mode expands the virtual-scroller and uses the page viewport to compute which items are visible. That way, you can use it in a big page with HTML elements before or after (like a header and a footer). Set the page-mode prop to true:

<header>
  <menu></menu>
</header>

<RecycleScroller page-mode>
  <!-- ... -->
</RecycleScroller>

<footer>
  Copyright 2017 - Cat
</footer>

Variable size mode

⚠️ This mode can be performance heavy with a lot of items. Use with caution.

If the itemSize prop is not set or is set to null, the virtual scroller will switch to variable size mode. You then need to expose a number field on the item objects with the size of the item element.

⚠️ You still need to set the size of the items with CSS correctly (with classes for example).

Use the sizeField prop (default is 'size') to set the field used by the scroller to get the size for each item.

Example:

const items = [
  {
    id: 1,
    label: 'Title',
    size: 64,
  },
  {
    id: 2,
    label: 'Foo',
    size: 32,
  },
  {
    id: 3,
    label: 'Bar',
    size: 32,
  },
]

Buffer

You can set the buffer prop (in pixels) on the virtual-scroller to extend the viewport considered when determining the visible items. For example, if you set a buffer of 1000 pixels, the virtual-scroller will start rendering items that are 1000 pixels below the bottom of the scroller visible area, and will keep the items that are 1000 pixels above the top of the visible area.

The default value is 200.

<RecycleScroller :buffer="200" />

Server-Side Rendering

The prerender props can be set as the number of items to render on the server inside the virtual scroller:

<RecycleScroller
  :items="items"
  :item-size="42"
  :prerender="10"
>

DynamicScroller

This works just like the RecycleScroller, but it can render items with unknown sizes!

Basic usage

<template>
  <DynamicScroller
    :items="items"
    :min-item-size="54"
    class="scroller"
  >
    <template v-slot="{ item, index, active }">
      <DynamicScrollerItem
        :item="item"
        :active="active"
        :size-dependencies="[
          item.message,
        ]"
        :data-index="index"
      >
        <div class="avatar">
          <img
            :src="item.avatar"
            :key="item.avatar"
            alt="avatar"
            class="image"
          >
        </div>
        <div class="text">{{ item.message }}</div>
      </DynamicScrollerItem>
    </template>
  </DynamicScroller>
</template>

<script>
export default {
  props: {
    items: Array,
  },
}
</script>

<style scoped>
.scroller {
  height: 100%;
}
</style>

Important notes

  • minItemSize is required for the initial render of items.
  • DynamicScroller won't detect size changes on its own, but you can put values that can affect the item size with size-dependencies on DynamicScrollerItem.
  • You don't need to have a size field on the items.

Props

Extends all the RecycleScroller props.

  • It's not recommended to change sizeField prop since all the size management is done internally.

Events

Extends all the RecycleScroller events.

Default scoped slot props

Extends all the RecycleScroller scoped slot props.

Other slots

Extends all the RecycleScroller other slots.

DynamicScrollerItem

The component that should wrap all the items in a DynamicScroller.

Props

  • item (required): the item rendered in the scroller.
  • active (required): is the holding view active in RecycleScroller. Will prevent unnecessary size recomputation.
  • sizeDependencies: values that can affect the size of the item. This prop will be watched and if one value changes, the size will be recomputed. Recommended instead of watchData.
  • watchData (default: false): deeply watch item for changes to re-calculate the size (not recommended, can impact performance).
  • tag (default: 'div'): element used to render the component.
  • emitResize (default: false): emit the resize event each time the size is recomputed (can impact performance).

Events

  • resize: emitted each time the size is recomputed, only if emitResize prop is true.

IdState

This is convenience mixin that can replace data in components being rendered in a RecycleScroller.

Why is this useful?

Since the components in RecycleScroller are reused, you can't directly use the Vue standard data properties: otherwise they will be shared with different items in the list!

IdState will instead provide an idState object which is equivalent to $data, but it's linked to a single item with its identifier (you can change which field with idProp param).

Example

In this example, we use the id of the item to have a "scoped" state to the item:

<template>
  <div class="question">
    <p>{{ item.question }}</p>
    <button @click="idState.replyOpen = !idState.replyOpen">Reply</button>
    <textarea
      v-if="idState.replyOpen"
      v-model="idState.replyText"
      placeholder="Type your reply"
    />
  </div>
</template>

<script>
import { IdState } from 'vue-virtual-scroller'

export default {
  mixins: [
    IdState({
      // You can customize this
      idProp: vm => vm.item.id,
    }),
  ],

  props: {
    // Item in the list
    item: Object,
  },

  // This replaces data () { ... }
  idState () {
    return {
      replyOpen: false,
      replyText: '',
    }
  },
}
</script>

Parameters

  • idProp (default: vm => vm.item.id): field name on the component (for example: 'id') or function returning the id.

License

MIT

Comments
  • fix: avoid infinite loop on scrollToBottom with unknown sized elements

    fix: avoid infinite loop on scrollToBottom with unknown sized elements

    fix #221

    I've changed the termination condition to when the scrollTop value is not changed since the previous update.

    Also added requestAnimationFrame during the loop because we need to wait delayed processing in RecycleView after triggering scroll event and DOM update.

    To check the behavior the scroll to bottom example has been updated not to specify fixed size for each item.

    opened by ktsn 22
  • how to use inside a table which has a header

    how to use inside a table which has a header

    How do i use it within an existing table that has a header?

    Since it wraps the content with two divs, it doesnt work here:

    <table>
      <thead><tr><th>...</th><th>...</th></tr>
      <virtual-scroller content-tag="tbody">
        <template>
            <tr>....</tr>
        <template>
      </virtual-scroller>
    </table>
    

    the content becomes treated as a cell, since it is a div, not a row (tr)

    question 
    opened by tonypee 19
  • Only last item visible

    Only last item visible

    First of all, thank you for the work you're doing. Really appreciate it.

    Anyhow, when updating to the new version and trying to change over to dynamicScroller I get it to scroll smoothly but only the last item (or at least I think it's the last one) is visible. So obviously I'm missing something but I can't find what it is. Worth mentioning is that when I'm scrolling down really fast I can see glimpses of the items but when I scroll back up they're not there anymore.

    Here's my implementation:

    <DynamicScroller
    style="height: 75vh"
    :items="dataToDisplay" 
    :min-item-height="200">
    	<template slot-scope="{ item, index, active }">
    		<DynamicScrollerItem
    		:item="item"
    		:active="active"
    		:data-index="index">
    		
    		    <v-card
    		    style="margin: 10px 0px;"
    		    class="rw-card card-hover">
    			<v-card-actions
    			 style="float: right;">
    				<v-spacer/>
    				<v-btn icon	flat color="error" @click="exclude(item)">
    					<v-icon>close</v-icon>
    				</v-btn>
    			 </v-card-actions>
    	                 <!--- .... all the card content here... -->
    		     </v-card>
    		</DynamicScrollerItem>
    	</template>
    </DynamicScroller>
    

    And importing the components as:

    import { DynamicScroller } from 'vue-virtual-scroller'
    import { DynamicScrollerItem } from 'vue-virtual-scroller'
    
    export default {
    	  props: ["input"],
    	  components:{
    		  DynamicScroller: DynamicScroller,
    		  DynamicScrollerItem: DynamicScrollerItem
    	  },
    

    Anyone got an idea of what I'm doing wrong?

    Addon 1: After further investigation it seems like it's rendering but outside of the viewport. So if i set height: 50% on the scroller i can scroll down and get one element showed and if using pagemode and then scrolling on the page I can scroll down and see everything but one element at the time, so somehow only one item is active.

    opened by karatekaneen 16
  • Space between items in the list is wrong

    Space between items in the list is wrong

    Hi,

    I am using the DynamicScroller for a chat app. When I add new items the space between them is not even close as it should be.

    image

    After I destroy and re-creeate the component(page refresh or v-if) it looks well: image

    Something similar happens when I add items at the top.

    I am using Vue 2 and vue-virtual-scroller version 1.0.10

    Any solution for this problem ? Thank you

    opened by dragos-boisteanu 12
  • Insert new item and scroll to the end (chat/stream)

    Insert new item and scroll to the end (chat/stream)

    So I'm currently working on a chat using this package for a more performant solution on how we render our chat items.

    Since chats work a bit different to normal lists I have some issues with the implementation of the automated scrolling when new messages are added. Also updates and resizing just resets the scroll position if changed manually via el.scrollTop = 1000 for example. Do I need to tell the component that the scroll position was updated and needs to be saved?

    scrollToItem isn't working for me, because it always scrolls to the beginning of the item instead of the end. Maybe implementing a scrollToEnd and scrollToStart would be good!

    Here is a codesandbox link: https://codesandbox.io/s/jn121l1n83

    enhancement 
    opened by bdbch 11
  • Stacking context issue

    Stacking context issue

    Hello, first of all - thank you for such a great script!

    I have a little problem with using multiselect plugin together with the dynamic scroller. It renders correctly only in one direction, which depends on scrolling direction.

    I've made a simple demo, select appear is in edit mode (double click): https://codesandbox.io/s/z-index-issue-rxkkx Check two selects at top and bottom of page - one of them will be under scroller rows.

    Any suggestion of how this could be fixed?

    opened by kilkujadek 10
  • Future of vue-virtual-scroller

    Future of vue-virtual-scroller

    Hello fellow watchers,

    I'm looking for some maintainers to continue the upkeep of this library along with myself.

    As we are all aware, there's been no releases or commits in this project since May. No issues or pull requests have been taken up. This is to no fault of Akryum – many of us do not pay for this software, and as such he is under no obligation to respond to these tickets.

    However, it goes without saying there are bugs that need fixing, fixes that need merging, and features that need coding, all piling up with nobody to care for them – and all of these need oversight to make sure they're good to go into production.

    I have contacted the maintainer over email to no avail, and his account looks fairly inactive. Until progress resumes on this repo, I have opened a fork at AkryumInfinitum/vue-virtual-scroller where I will start testing and merging PRs, as well as working on issues.

    As time goes on, I may take other popular projects of his that have lost steam and pull them over, which is why it is sitting in its own organization.

    If anyone is interested in being a fellow maintainer of this fork, you can email me at [email protected]

    opened by EricRabil 9
  • Can I submit a PR for horizontal scroll ?

    Can I submit a PR for horizontal scroll ?

    I've had a brief look through the code, and it seems that it wouldn't be too difficult to support horizontal scrolling, unless there are any technical reasons, of course, as browsers default to vertical.

    I propose:

    • adding a new prop direction to take vertical | horizontal
      • alternatively, axis to take x | y
    • modifying anything to do with height to size
    • adding computed properties for internals which depending on direction return the right values for:
      • height or y
      • width or x

    I'm happy to start this tomorrow as I think it would be the solution to an issue I have right now on a live project.

    Would this be OK @Akryum ?

    question 
    opened by davestewart 9
  • Failed to execute 'unobserve' on 'ResizeObserver': parameter 1 is not of type 'Element'.

    Failed to execute 'unobserve' on 'ResizeObserver': parameter 1 is not of type 'Element'.

    Sine I upgraded from v1.0.0-rc.2 to the latest version 1.0.10 I get the following errors in the console when scrolling in the dynamic scroller. Also the different elements, in my case messages, are not getting rendered properly and are somtimes overlapping.

    [Vue warn]: Error in beforeDestroy hook: "TypeError: Failed to execute 'unobserve' on 'ResizeObserver': parameter 1 is not of type 'Element'."
    
    found in
    
    ---> <DynamicScrollerItem>
           <RecycleScroller>
             <DynamicScroller>
               <ChatHistory> at src/components/chat/ChatHistory.vue
                 <Chat> at src/components/chat/Chat.vue
                   <QPage>
                     <Chat> at src/pages/Chat.vue
                       <QPageContainer>
                         <QLayout>
                           <DesktopLayout> at src/layouts/DesktopLayout.vue
                             <App> at src/App.vue
                               <Root>
    
    TypeError: Failed to execute 'unobserve' on 'ResizeObserver': parameter 1 is not of type 'Element'.
        at VueComponent.unobserveSize (vue-virtual-scroller.esm.js?25de:1390)
        at VueComponent.beforeDestroy (vue-virtual-scroller.esm.js?25de:1311)
        at invokeWithErrorHandling (vue.runtime.esm.js?5593:1854)
        at callHook (vue.runtime.esm.js?5593:4219)
        at VueComponent.Vue.$destroy (vue.runtime.esm.js?5593:3978)
        at destroy (vue.runtime.esm.js?5593:3159)
        at invokeDestroyHook (vue.runtime.esm.js?5593:6114)
        at removeVnodes (vue.runtime.esm.js?5593:6130)
        at updateChildren (vue.runtime.esm.js?5593:6235)
        at patchVnode (vue.runtime.esm.js?5593:6319)
    

    Any Idea what changes since the version I was using are causing this issues? I pretty much onfigured the dynamic scroller as described in the README:

    <DynamicScroller
            id="dynamic-scroller-id"
            :items="messageHistory"
            :min-item-size="54"
            key-field="id"
            page-mode
            :buffer="2000"
            class="content-center justify-center q-pb-xs"
            style="max-width: 812px; margin: 0 auto"
        >
            <template v-slot="{ item, index, active }">
                <DynamicScrollerItem
                    :item="item"
                    :active="active"
                    :data-index="index"
                    :sizeDependencies="[item.content]"
                    :key="item.content.length"
                >
                    <ChatMessage @clickMedia="openDialogChatMessageMediaFullscreen" :key="item.id" ref="chatMessage" :message="item" :isGroup="isGroup" :showAvatar="showAvatar" :minify="minify"/>
                </DynamicScrollerItem>
            </template>
        </DynamicScroller>
    

    Many thanks in advance!

    opened by Quasarman 8
  • min-item-height problem

    min-item-height problem

    @Akryum Hello! First of all thanks for your great work! It's userful for my program.

    I am using the DynamicScroller component and set its minItemHeight 36px as required. As you say:

    minItemHeight is required for the initial render of items.

    Then I add an element with 79px height (or unknown height) and emit scrollToItem function but its position is not correct. I view the console and find that the component seems to calculate the element(unknown height)'s height as the minItemHeight.

    How can I fix this problem? I am looking forward to your suggestion. Thanks a lot.

    enhancement 
    opened by AceLing 8
  • No items are shown - height is 0px after latest update

    No items are shown - height is 0px after latest update

    Describe the bug

    After this last update, the component renders as 0px height so no items are shown.

    • item-size = 72
    • items are visible in dev tools

    Same settings worked fine before this update

    image

    Reproduction

    NIL

    System Info

    System:
        OS: Windows 10 10.0.19044
        CPU: (8) x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
        Memory: 14.62 GB / 31.83 GB
      Binaries:
        Node: 18.4.0 - C:\Program Files\nodejs\node.EXE
        npm: 8.19.2 - C:\Program Files\nodejs\npm.CMD
      Browsers:
        Edge: Spartan (44.19041.1266.0), Chromium (106.0.1370.42)
        Internet Explorer: 11.0.19041.1566
    

    Used Package Manager

    pnpm

    Validations

    need-repro 
    opened by CharlesOkwuagwu 7
  • version1.1.2 do not use table tag ?

    version1.1.2 do not use table tag ?

    Describe the bug

    I'm trying to implement virtual-table by using [email protected] 。But I found vue-virtual-scroller doesnot surport table tag。

     <table>
          <colgroup>
            <col width="400">
            <col width="400">
            <col width="400">
          </colgroup>
          <RecycleScroller
            tag="table"
            :items="items"
            :item-size="42"
            list-tag="tbody"
            item-tag="tr"
            key-field="_id"
            page-mode
          >
            <template slot-scope="props">
              <td>{{ props.item.picture }}</td>
              <td>{{ props.item.name }}</td>
              <td>{{ props.item.company }}</td>
            </template>
          </RecycleScroller>
        </table>
    

    After web page rendered,I found dom structure is not right.

    <table>
    	<colgroup>
    		<col width="400">
    		<col width="400">
    		<col width="400">
    	</colgroup>
    	<div class="vue-recycle-scroller ready page-mode direction-vertical" tag="table">
    		<!---->
    		<tbody class="vue-recycle-scroller__item-wrapper" style="min-height: 208992px;">
    			<tr class="vue-recycle-scroller__item-view" style="transform: translateY(0px) translateX(0px);">
    				<td>http://placehold.it/32x32</td>
    				<td>Compton Albert</td>
    				<td>ZAPPIX</td>
    			</tr>
    			<tr class="vue-recycle-scroller__item-view" style="transform: translateY(42px) translateX(0px);">
    				<td>http://placehold.it/32x32</td>
    				<td>Daugherty Irwin</td>
    				<td>VELITY</td>
    			</tr>
    			<tr class="vue-recycle-scroller__item-view" style="transform: translateY(84px) translateX(0px);">
    				<td>http://placehold.it/32x32</td>
    				<td>Hopkins Ramos</td>
    				<td>EXOSPACE</td>
    			</tr>
    			<tr class="vue-recycle-scroller__item-view" style="transform: translateY(126px) translateX(0px);">
    				<td>http://placehold.it/32x32</td>
    				<td>Stanton Wilcox</td>
    				<td>SURELOGIC</td>
    			</tr>
    			<tr class="vue-recycle-scroller__item-view" style="transform: translateY(168px) translateX(0px);">
    				<td>http://placehold.it/32x32</td>
    				<td>Savannah Guzman</td>
    				<td>HARMONEY</td>
    			</tr>
    		</tbody>
    		<!---->
    		<div data-v-b329ee4c="" tabindex="-1" class="resize-observer">
    			<object aria-hidden="true" tabindex="-1" type="text/html" data="about:blank"></object>
    		</div>
    	</div>
    </table>
    

    So What am I to do?

    Reproduction

    https://github.com/Akryum/vue-virtual-scroller/issues/new?assignees=&labels=to+triage&template=bug-report.yml

    System Info

    npm install
    

    Used Package Manager

    npm

    Validations

    opened by Create-Peace 0
  • Support scrollIntoItem by visible view section

    Support scrollIntoItem by visible view section

    Clear and concise description of the problem

    I'm trying to do scrollbar control like spotlight in MacOS. scroll-demo

    As can be seen from the gif, the scrollbar only changed when the view section is not be able to render the rest of items which actually in the virtual scroller.

    Suggested solution

    I did a simple demo and it works for me on my local laptop so i forked this project into my owns. My idea is extending RecycleScroller, make the scrollIntoItem functional support and expose the method for developer who have same scenarios. And also I think it is very general for many scenes.

    Alternative

    No response

    Additional context

    No response

    Validations

    • [X] Read the docs.
    • [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
    opened by Matrixbirds 0
  • Bug introduced in v1.1.2, possible cause in description

    Bug introduced in v1.1.2, possible cause in description

    Describe the bug

    After updating to v1.1.2 we started seeing some strange issues in lists using DynamicScroller. Data seems to be reused from other rows. Downgrading to v1.1.1 resolved the issue. Looking at the diff between these two versions, we noticed a highly suspicious code change.

    image

    view.item is an object in our case, and keyField defines how to compare this with existing elements. Direct strict object equality doesn't work even if the objects would have the same contents.

    Are we using the library wrong, or is this an unintended change?

    Manually reverting this line resolves the problem (with the rest of the code from v1.1.2).

    Reproduction

    The current issue is deep within our application, and I'm hoping the description above is clear enough. If it is not, I will try to reproduce with something smaller.

    System Info

    System:
        OS: macOS 13.0.1
        CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
        Memory: 101.58 MB / 16.00 GB
        Shell: 5.8.1 - /bin/zsh
      Binaries:
        Node: 19.3.0 - /usr/local/bin/node
        Yarn: 1.22.17 - /usr/local/bin/yarn
        npm: 9.1.1 - ~/node_modules/.bin/npm
      Browsers:
        Chrome: 108.0.5359.124
        Chrome Canary: 111.0.5486.0
        Firefox: 106.0.2
        Safari: 16.1
      npmPackages:
        vue: ^2.6.14 => 2.6.14
        vue-virtual-scroller: ^1.1.2 => 1.1.2
    

    Used Package Manager

    npm

    Validations

    opened by Krisell 4
  • Component Import TS Error

    Component Import TS Error

    Describe the bug

    When importing components directly (instead of using the plugin), I receive the following error:

    Module '"vue-virtual-scroller"' has no exported member 'DynamicScroller'.ts(2305)
    Module '"vue-virtual-scroller"' has no exported member 'DynamicScrollerItem'.ts(2305)
    

    Reproduction

    import { DynamicScroller, DynamicScrollerItem } from "vue-virtual-scroller";

    System Info

    N/A
    

    Used Package Manager

    pnpm

    Validations

    opened by kgosen 0
  • Items with images bounce when scrolling in DynamicScroller

    Items with images bounce when scrolling in DynamicScroller

    Describe the bug

    I have items, some with pictures, some without. When I scroll to the end of the list and then scroll to the top, I see bouncing items. It doesn't always happen, but often.

    Reproduction

    https://codesandbox.io/s/twilight-worker-blx0ej vue: 3.2.45 vue-virtual-scroller: 2.0.0-beta.7

    Reproduced with: 2.0.0-beta.5, 2.0.0-beta.6, 2.0.0-beta.7

    I am currently using 2.0.0-beta.4 and everything is fine with this version.

    Video of issue: https://user-images.githubusercontent.com/85647729/207878030-a6e62cff-9f7b-48bb-a24e-da17d684b5b8.mov

    System Info

    System:
        OS: macOS 12.2.1
        CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
        Memory: 33.79 MB / 16.00 GB
        Shell: 5.8 - /bin/zsh
      Binaries:
        Node: 14.20.0 - /usr/local/bin/node
        Yarn: 1.22.11 - /usr/local/bin/yarn
        npm: 6.14.17 - /usr/local/bin/npm
      Browsers:
        Chrome: 108.0.5359.98
        Firefox: 107.0
        Safari: 15.3
      npmPackages:
        vue: ^2.6.14 => 2.6.14 
        vue-virtual-scroller: 2.0.0-beta.5 => 1.0.10
    

    Used Package Manager

    yarn

    Validations

    opened by umbrellait-arkady-chucvaga 0
Releases(v2.0.0-beta.7)
  • v2.0.0-beta.7(Dec 14, 2022)

  • v2.0.0-beta.6(Dec 14, 2022)

  • v2.0.0-beta.5(Dec 7, 2022)

  • v2.0.0-beta.4(Dec 6, 2022)

  • v2.0.0-beta.3(Oct 18, 2022)

  • v1.1.2(Oct 18, 2022)

  • v2.0.0-beta.2(Oct 17, 2022)

  • v1.1.1(Oct 17, 2022)

  • v2.0.0-beta.1(Oct 15, 2022)

    Bug Fixes

    • Account for the height of the leading and trailing slots when calculating visible items, fix #685 (24ab3ba)
    • avoid jumping scroll position when upper item size is calculated (#374) (fd58a95)
    • clamp endIndex if less items than prerender (#473) (f9124aa)
    • DynamicScroller should pass its own keyField prop to child RecycleScroller (#732) (9673679)
    • DynamicScrollerItem: watch item prop (#700) (4d3b956)
    • issue with beforeDestroy hook (#748) (59f3f1b)
    • merge (c8363b1)
    • restore scroll in keep-alive (#724) (5011e06)
    • scrollToItem works with pageMode (#396) (c9772bf)
    • wrap the callback in requestAnimationFrame, fix #516 (#517) (6f359ab)

    Features

    • add an empty slot (#398) (5c2715c)
    • add skipHover prop to deactive the hover detection (#752) (b613318)
    • adds configurable list/item tags for semantic html (#203) (3d24dc3)
    • custom classes for list wrapper and list items. (#397) (32b285d)
    • Emit events for scroll to begin and end of list (#364) (2a7bfd4)
    • gridItems prop (#27) (6339e72)
    • itemSecondarySize (43d311c)
    • throw error when key field does not exist in item (#265) (c63129f)
    • update event provide range of the visible items (#115) (f19af6c)

    Performance Improvements

    • skipHover: don't add event listeners (6b623b5)
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Oct 14, 2022)

    Features

    • Create grids with the new gridItems prop (#27)
    • New itemSecondarySize prop
    • add skipHover prop to deactive the hover detection (#752)
    • update event provide range of the visible items (#115)
    • adds configurable list/item tags for semantic html (#203)
    • throw error when key field does not exist in item (#265)
    • custom classes for list wrapper and list items. (#397)
    • add an empty slot (#398)
    • Emit events for scroll to begin and end of list (#364)

    Bug fixes

    • DynamicScrollerItem: watch item prop (#700)
    • Account for the height of the leading and trailing slots when calculating visible items, fix #685
    • restore scroll in keep-alive (#724)
    • DynamicScroller should pass its own keyField prop to child RecycleScroller (#732)
    • issue with beforeDestroy hook (#748)
    • avoid jumping scroll position when upper item size is calculated (#374)
    • scrollToItem works with pageMode (#396)
    • clamp endIndex if less items than prerender (#473)
    • wrap the callback in requestAnimationFrame, fix #516 (#517)
    Source code(tar.gz)
    Source code(zip)
  • v1.0.10(Apr 17, 2020)

  • v1.0.9(Apr 15, 2020)

  • v1.0.7(Apr 15, 2020)

  • v1.0.6(Apr 14, 2020)

    Fixed

    • Item with wrong heights if the scroller is created but hidden while the items are added
    • ssr: template mismatch, closes #343

    Improved

    • sort views after scrolling so text selection is correct, closes #359
    • perf: skip update if the user hasn't scrolled more than min item height
    Source code(tar.gz)
    Source code(zip)
  • v1.0.4(Mar 31, 2020)

  • v1.0.3(Mar 31, 2020)

    New

    • On supported browsers, uses a ResizeObserver to more accurately detect size changes for DynamicScrollerItem

    Improved

    • Improved scrollToBottom implementation

    Fixed

    • Exclude dependencies for esm build (#257, #207)

    Other

    • Updated rollup and build toolchain
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-rc.2(Feb 21, 2019)

  • v1.0.0-rc.1(Feb 20, 2019)

    BREAKING CHANGES

    • Renamed props in RecycleScroller and DynamicScroller:
    itemHeight => itemSize
    minItemHeight => minItemSize
    heightField => sizeField
    
    • Renamed slots in RecycleScroller and DynamicScroller:
    before-container => before
    after-container => after
    
    • Slot variables changed in DynamicScroller:
    itemWithHeight => itemWithSize
    

    New

    • direction prop (either 'vertical' or 'horizontal')

    Fixed

    • Do not forward keyField prop from DynamicScroller - closes #132 (#133)
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta.7(Feb 20, 2019)

    New

    • DynamicScroller: support simple arrays, closes #108

    Fixed

    • DynamicScroller: round height, closes #118
    • use minHeight instead of height on wrapper, closes #92
    • ssr: document could not be defined, closes #112
    • dynamic scroller: invalidate heights instead of clear, closes #130
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta.6(Feb 19, 2019)

  • v1.0.0-beta.5(Feb 10, 2019)

  • v1.0.0-beta.4(Dec 22, 2018)

  • v1.0.0-beta.3(Dec 21, 2018)

  • v1.0.0-beta.2(Oct 9, 2018)

  • v1.0.0-beta.1(Oct 8, 2018)

    Breaking changes

    • virtual-scroller component is removed (it was much slower than the recycling one, and what we need is more performance!).
    • recycle-list was renamed to RecycleScroller

    New

    • DynamicScroller and DynamicScrollerItem components to create virtual scroller with unknown height items. It's fully automatic! :fire:
    • IdState mixin to ease data management for components inside a recycling scroller (components are reused!)

    Improved

    • Docs are completely reworked.
    Source code(tar.gz)
    Source code(zip)
  • v0.12.2(Oct 4, 2018)

    New

    • <recycle-list>: new hidden event (opposite of visible event).
    • <recycle-list>: add before-container slot

    Improved

    • Updated vue-observe-visibility

    Fixed

    • The default target for IOS should be body, closes #73 (#85)
    Source code(tar.gz)
    Source code(zip)
  • v0.12.0(Jun 2, 2018)

  • v0.11.0(Jan 25, 2018)

  • v0.10.5(Oct 30, 2017)

  • v0.10.4(Oct 26, 2017)

    New

    • New 'visible' event emitted when the scroller becomes visible
    • The behavior introduced in 0.10.2 (defer removing previous items) is now disabled by default and enabled with the delay-previous-items boolean prop.
    Source code(tar.gz)
    Source code(zip)
Owner
Guillaume Chau
Web & JavaScript enthusiast, @vuejs core team.
Guillaume Chau
Vuejs library for virtual scrolling

vue-virtualscroll Vuejs library for virtual scrolling npm i vue-virtualscroll import VueVirtualScroll from 'vue-virtualscroll' <vue-virtual-scroll :h

David Grill 15 Jul 30, 2020
Virtual Scrolling Grid made for VueJS based on CSS grids.

Vue Virtual Grid Virtual Scrolling Grid made for VueJS based on CSS grids. NPM Package | Demo Website Render any Vue Component (images, iframes, conte

Corentin Mors 44 Dec 23, 2022
A simple Vue blog template that displays posts from any WordPress REST API endpoint.

WP Vue This is just a simple Vue application (scaffolded using the Vue CLI) that pulls posts from a WordPress REST API endpoint. Clone or fork this su

Alex MacArthur 448 Dec 27, 2022
🏎 Fast and furious Nuxt development

?? Rapide The new-gen experience with Nuxt 2. ?? Latest Nuxt version ?? Composition API, the new Vue paradigm ?? Vite, the modern bundler ?? WindiCSS,

Yaël Guilloux 15 Aug 9, 2021
A fast, composable, unstyled command palette interface for Vue.

Command Palette for Vue A fast, composable, unstyled command + k interface (Command Palette) for Vue. Preview Concepts Command palette interfaces are

Yunwei Xiao 298 Jan 3, 2023
Vue component for efficiently rendering large collection data

vue-virtual-collection Vue component for efficiently rendering large collection data. Inspired by react-virtualize. Demo Table of Contents generated w

Weijia Wang 604 Dec 19, 2022
Vue component for efficiently rendering large collection data. Inspired by react-virtualize.

vue-virtual-collection Vue component for efficiently rendering large collection data. Inspired by react-virtualize. Demo Table of Contents generated w

Weijia Wang 604 Dec 19, 2022
An experiment utilizing WebView with Go to find the most efficient methods of accessing a commonly used data-set

Arreat This was an experiment utilizing WebView with Go to find the most efficie

null 0 Dec 23, 2021
Blazing fast scrolling and updating for any amount of list and hierarchical data.

Vue Virtualised Vue components developed by Vue.js 3.0 for efficiently rendering large scrollable lists and hierarchical data. vue-virtualised is able

Junxiang Chen 18 Sep 13, 2022
⚡️ Blazing fast scrolling for any amount of data

vue-virtual-scroller Blazing fast scrolling of any amount of data | Live demo | Video demo For Vue 3 support, see here ??️ Become a Sponsor Sponsors T

Guillaume Chau 7.5k Jan 1, 2023
The easy & modern way to work with tables of any size. Blazing-fast searching, filtering, sorting, and paginating

The easy & modern way to work with tables of any size. Blazing-fast searching, filtering, sorting, and paginating. Powered by your search engine of choice. Kick-start the development of a feature-rich & configurable table UI, including a beautiful default UX.

Open Web Foundation 10 Nov 21, 2022
A highly customizable and blazing fast Vue tree component ⚡🌲

VueJS Tree A highly customizable vuejs tree viewer Example codesandbox Getting Started Install You can install using yarn: $ yarn add vuejs-tree or wi

Scalia 302 Dec 7, 2022
:star: Rating component in Semantic-UI made with VueJS ( 1kB, blazing fast)

V-Rating ⚡ Simple ui rating component for Vue made with Semantic-UI. This is on GitHub so let me know if I've b0rked it somewhere, give me a star ⭐ if

Vinayak Kulkarni 47 Nov 11, 2022
A blazing fast start-page for your services written with Nuxt3 and Go

Launchpad #################### ARCHIVED #################### I moved over to a go-only approach (SPEED!) and created a new project: https://github.com

UNjX 11 Dec 31, 2022
⚡️A vue component support big amount data list with high render performance and efficient.

Table of contents Advantages Live demo Simple usage Props type Required props Optional props Public methods Attentions Advantages Only 3 required prop

Stephan Tang 3.8k Jan 3, 2023
Tree component for large amount of data, base on Vue3

vue-virtual-tree Based on the tree component encapsulated by vue3 and dedicated to large data volume, if the data volume is not large, using this comp

Madao 59 Dec 6, 2022
Vue component who put SortableJS/Vue.Draggable and tangbc/vue-virtual-scroll-list together and allow drag-and-drop and big amount data list with high scroll performance.

Vue component who put SortableJS/Vue.Draggable and tangbc/vue-virtual-scroll-list together and allow drag-and-drop and big amount data list with high scroll performance.

Tajima Jumpei 34 Nov 20, 2022
↕ A simple but fast & powerful library to animate HTML elements while scrolling pages.

Vue Scroll Animator ↕ A simple but fast & powerful library to animate HTML elements while scrolling pages. Installation npm install @byloth/vue-scroll

Matteo Bilotta 0 May 19, 2022
Confirmation button for sensitive action, which requires to be hold for an amount of seconds

VueLongpress A VueJS (2.x) button component that requires you to keep pressing to confirm a given action. DEMO Live demo on jsFiddle What is this? A c

Javis V. Pérez 74 Nov 11, 2022
Laravel Enso Form Builder is a customizable, template based form creator, so you can quickly create forms with the minimum amount of effort

Forms JSON-based Form builder for Laravel Enso This package can work independently of the Enso ecosystem. The front end implementation that utilizes t

Laravel Enso 119 Dec 24, 2022