@yasanchezz/vue-infinite-grid
v0.1.11
Published
Readme
@yasanchezz/vue-infinite-grid
An infinite (virtualized) grid component for Vue 3.5+
VueGrid renders only the rows that fit near the visible viewport (plus a
buffer) and keeps scroll height consistent by measuring each rendered row
with a ResizeObserver. It relies on CSS Grid + subgrid,
so your rows must be laid out as a grid that spans the full width of the
component.
Installation
Install the npm package
npm install @yasanchezz/vue-infinite-grid --save
Register it as a global component in main.js
import VueGrid from '@yasanchezz/vue-infinite-grid';
import '@yasanchezz/vue-infinite-grid/dist/vue-infinite-grid.css';
createApp(App)
.use(VueGrid)
.mount('#app');Usage
<template>
<VueGrid
ref="grid"
:rows="rows"
:rows-count="10"
:height="200"
class="my-grid"
>
<template #row="{ row }">
<SubgridComponent
class="my-subgrid"
:row="row"
/>
</template>
</VueGrid>
</template>
<style lang="scss" scoped>
.my-grid {
grid-template-columns: repeat(4, 1fr);
}
.my-subgrid {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid;
}
</style>Each item in rows must have a unique id: string, which VueGrid uses as
the :key for the row and to track its measured height.
Props
| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| rows | GridRow[] ({ id: string }) | yes | - | The full list of rows. Only a window of these is actually rendered at a time. |
| rowsCount | number | yes | - | How many rows to render at once (the size of the rendered window). |
| height | number | yes | - | Estimated row height in px, used for scroll/offset math before a row has actually been measured. |
| container | Element \| null \| ((container: Element \| null) => Element \| null \| undefined) | no | document.documentElement | The scrollable element to listen to. Can be a function that receives the grid's root element (useful for resolving a custom scroll container after mount). |
| autoCalculatedRowsCount | boolean | no | false | When true, grows the rendered window beyond rowsCount based on measured row heights so it always covers the viewport (useful when actual row heights are smaller than the estimated height). |
Slots
| Slot | Props | Description |
| --- | --- | --- |
| row | { row: GridRow } | Renders a single row. Required. |
Exposed methods
| Method | Signature | Description |
| --- | --- | --- |
| init | () => void | Recalculates the rendered window and layout. Call this after something outside of rows/height changes the available space, e.g. on window resize. |
| scrollTo | (id: string) => Promise<HTMLElement> | Scrolls the container to the row with the given id and resolves with that row's DOM element once it has been rendered. |
Usage as a ref
<script setup>
import { useTemplateRef } from 'vue'
const grid = useTemplateRef('grid')
grid.value.scrollTo(rowId) // scroll to a specific row
window.addEventListener('resize', () => grid.value.init()) // recalculate layout on resize
</script>
<template>
<VueGrid ref="grid" :rows="rows" :rows-count="10" :height="200" />
</template>Styling notes
VueGrid only controls vertical layout - you're expected to define the
column layout on the root element (e.g. grid-template-columns) and have
each row use display: grid; grid-template-columns: subgrid; spanning
grid-column: 1 / -1 so it inherits those columns.
