This is a reusable component for Vue 3 that renders a list with a huge number of items (e.g. 1000+ items) as a grid in a performant way.
npm install @sarast/vue-virtual-scroll-gridThis is a reusable component for Vue 3 that renders a list with a huge number of
items (e.g. 1000+ items) as a grid in a performant way.
- [Demo][demo]
- [NPM Package][npm]
- Use virtual-scrolling / windowing to render the items, so the number of DOM
nodes is kept low.
- Just use CSS grid to style your grid. Minimum styling opinions form the
library.
- Support using a paginated API to load the items in the background.
- Support rendering placeholders for unloaded items.
- Support both vertical and horizontal scroll.
- Loaded items are cached for better performance.
- [As an ES module (with a bundler)][esm]
- [As a Universal Module Definition (no bundler)][umd]
``shell`
npm install vue-virtual-scroll-grid
| Name | Description | Type | Validation |
| -------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------- |
| length | The number of items in the list | number | Required, an integer greater than or equal to 0 |pageProvider
| | The callback that returns a page of items as a promise. pageNumber start with 0 | (pageNumber: number, pageSize: number) => Promise | Required |pageSize
| | The number of items in a page from the item provider (e.g. a backend API) | number | Required, an integer greater than or equal to 1 |pageProviderDebounceTime
| | Debounce window in milliseconds on the calls to pageProvider | number | Optional, an integer greater than or equal to 0, defaults to 0 |probeTag
| | The HTML tag used as probe element. Default value is div | string | Optional, any valid HTML tag, defaults to div |respectScrollToOnResize
| | Snap to the position set by scrollTo when the grid container is resized | boolean | Optional, defaults to false |scrollBehavior
| | The behavior of scrollTo. Default value is smooth | smooth | auto | Optional, a string to be smooth or auto, defaults to smooth |scrollTo
| | Scroll to a specific item by index | number | Optional, an integer from 0 to the length prop - 1, defaults to 0 |tag
| | The HTML tag used as container element. Default value is div | string | Optional, any valid HTML tag, defaults to div |getKey
| | The :key used on each grid item. Auto-generated, but overwritable via function | (internalItem: InternalItem) => number \| string 1| Optional, any valid Function that returns a string or number |
Example:
`vue`
:pageProvider="async (pageNumber, pageSize) => Array(pageSize).fill('x')"
:pageSize="40"
:scrollTo="10"
>
There are 3 scoped slots: default, placeholder and probe.
The default slot is used to render a loaded item.
Props:
- item: the loaded item that is used for rendering your itemindex
element/component.
- : the index of current item within the list.style
- : the style object provided by the library that need to be set on the
item element/component.
Example:
`vue`
{{ item }} {{ index }}
When an item is not loaded, the component/element in the placeholder slot willplaceholder
be used for rendering. The slot is optional. If missing, the space
of unloaded items will be blank until they are loaded.
Props:
- index: the index of current item within the list.style
- : the style object provided by the library that need to be set on the
item element/component.
Example:
`vue`
Placeholder {{ index }}
The probe slot is used to measure the visual size of grid item. It has noplaceholder
prop. You can pass the same element/component for the slot. **If not provided, you must set a fixed heightgrid-template-rows
to on your CSS grid, e.g. 200px. If provided, make suredefault
it is styled with the same dimensions as rendered items in the placeholder
or slot. Otherwise, the view wouldn't be rendered properly, or the
rendering could be very slow.**
Example:
`vue`
Probe
* allItems: All items memoized by the grid
The library uses grid-auto-flow CSS property to infer scroll mode. Set it tocolumn value if you want to enable horizontal scroll.
The library does not require items have foreknown width and height, but do
require them to be styled with the same width and height under a view. E.g. the
items can be 200px x 200px when the view is under 768px and 300px x 500px above
768px.
Required environment variables:
- VITE_APP_ID: An Algolia app IDVITE_SEARCH_ONLY_API_KEY
- : The search API key for the Algolia app above
* Setup: npm installnpm run dev
* Run dev server: npm run lint
* Lint (type check): npm run build
* Build the library: npm run build -- --mode=demo
* Build the demo: npm run serve `
* Preview the locally built demo:
We use [semantic-release][semantic-release] to release the library on npm
automatically.
[demo]: https://grid.kiwiberry.nz/
[npm]: https://www.npmjs.com/package/vue-virtual-scroll-grid
[esm]: https://codesandbox.io/s/vue-virtual-scroll-grid-esm-vt27c?file=/App.vue
[umd]: https://codesandbox.io/s/vue-virtual-scroll-grid-umd-k14w5?file=/index.html
[semantic-release]: https://semantic-release.gitbook.io/semantic-release/#how-does-it-work