151 |
152 |
153 |
180 |
181 |
310 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Virtual Scroll Grid for Vue 3
2 |
3 | This is a reusable component for Vue 3 that renders a list with a huge number of
4 | items (e.g. 1000+ items) as a grid in a performant way.
5 |
6 | - [Demo][demo]
7 | - [NPM Package][npm]
8 |
9 | ## Features
10 |
11 | - Use virtual-scrolling / windowing to render the items, so the number of DOM
12 | nodes is kept low.
13 | - Just use CSS grid to style your grid. Minimum styling opinions form the
14 | library.
15 | - Support using a paginated API to load the items in the background.
16 | - Support rendering placeholders for unloaded items.
17 | - Support both vertical and horizontal scroll.
18 | - Loaded items are cached for better performance.
19 |
20 | ## Code Examples
21 |
22 | - [As an ES module (with a bundler)][esm]
23 | - [As a Universal Module Definition (no bundler)][umd]
24 |
25 | ## Install
26 |
27 | ```shell
28 | npm install vue-virtual-scroll-grid
29 | ```
30 |
31 | ## Available Props
32 |
33 | | Name | Description | Type | Validation |
34 | | -------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------- |
35 | | `length` | The number of items in the list | `number` | Required, an integer greater than or equal to 0 |
36 | | `pageProvider` | The callback that returns a page of items as a promise. `pageNumber` start with 0 | `(pageNumber: number, pageSize: number) => Promise` | Required |
37 | | `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 |
38 | | `pageProviderDebounceTime` | Debounce window in milliseconds on the calls to `pageProvider` | `number` | Optional, an integer greater than or equal to 0, defaults to `0` |
39 | | `probeTag` | The HTML tag used as probe element. Default value is `div` | `string` | Optional, any valid HTML tag, defaults to `div` |
40 | | `respectScrollToOnResize` | Snap to the position set by `scrollTo` when the grid container is resized | `boolean` | Optional, defaults to `false` |
41 | | `scrollBehavior` | The behavior of `scrollTo`. Default value is `smooth` | `smooth` | `auto` | Optional, a string to be `smooth` or `auto`, defaults to `smooth` |
42 | | `scrollTo` | Scroll to a specific item by index | `number` | Optional, an integer from 0 to the `length` prop - 1, defaults to 0 |
43 | | `tag` | The HTML tag used as container element. Default value is `div` | `string` | Optional, any valid HTML tag, defaults to `div` |
44 | | `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` |
45 |
46 | Example:
47 |
48 | ```vue
49 |
55 |
56 |
57 | ```
58 |
59 | ## Available Slots
60 |
61 | There are 3 scoped slots: `default`, `placeholder` and `probe`.
62 |
63 | ### The `default` slot
64 |
65 | The `default` slot is used to render a loaded item.
66 |
67 | Props:
68 |
69 | - `item`: the loaded item that is used for rendering your item
70 | element/component.
71 | - `index`: the index of current item within the list.
72 | - `style`: the style object provided by the library that need to be set on the
73 | item element/component.
74 |
75 | Example:
76 |
77 | ```vue
78 |
79 |
{{ item }} {{ index }}
80 |
81 | ```
82 |
83 | ### The`placeholder` slot
84 |
85 | When an item is not loaded, the component/element in the `placeholder` slot will
86 | be used for rendering. The `placeholder` slot is optional. If missing, the space
87 | of unloaded items will be blank until they are loaded.
88 |
89 | Props:
90 |
91 | - `index`: the index of current item within the list.
92 | - `style`: the style object provided by the library that need to be set on the
93 | item element/component.
94 |
95 | Example:
96 |
97 | ```vue
98 |
99 |
Placeholder {{ index }}
100 |
101 | ```
102 |
103 | ### The `probe` slot
104 |
105 | The `probe` slot is used to measure the visual size of grid item. It has no
106 | prop. You can pass the same element/component for the
107 | `placeholder` slot. **If not provided, you must set a fixed height
108 | to `grid-template-rows` on your CSS grid, e.g. `200px`. If provided, make sure
109 | it is styled with the same dimensions as rendered items in the `default`
110 | or `placeholder` slot. Otherwise, the view wouldn't be rendered properly, or the
111 | rendering could be very slow.**
112 |
113 | Example:
114 |
115 | ```vue
116 |
117 |
Probe
118 |
119 | ```
120 |
121 | ## Exposed Public Properties
122 |
123 | * `allItems`: All items memoized by the grid
124 |
125 | ## Scroll Mode
126 |
127 | The library uses `grid-auto-flow` CSS property to infer scroll mode. Set it to
128 | `column` value if you want to enable horizontal scroll.
129 |
130 | ## Caveats
131 |
132 | The library does not require items have foreknown width and height, but do
133 | require them to be styled with the same width and height under a view. E.g. the
134 | items can be 200px x 200px when the view is under 768px and 300px x 500px above
135 | 768px.
136 |
137 | ## Development
138 |
139 | Required environment variables:
140 |
141 | - `VITE_APP_ID`: An Algolia app ID
142 | - `VITE_SEARCH_ONLY_API_KEY`: The search API key for the Algolia app above
143 |
144 | * Setup: `npm install`
145 | * Run dev server: `npm run dev `
146 | * Lint (type check): `npm run lint `
147 | * Build the library: `npm run build `
148 | * Build the demo: `npm run build -- --mode=demo `
149 | * Preview the locally built demo: `npm run serve `
150 |
151 | ### How to Release a New Version
152 |
153 | We use [semantic-release][semantic-release] to release the library on npm
154 | automatically.
155 |
156 | [demo]: https://grid.kiwiberry.nz/
157 | [npm]: https://www.npmjs.com/package/vue-virtual-scroll-grid
158 | [esm]: https://codesandbox.io/s/vue-virtual-scroll-grid-esm-vt27c?file=/App.vue
159 | [umd]: https://codesandbox.io/s/vue-virtual-scroll-grid-umd-k14w5?file=/index.html
160 | [semantic-release]: https://semantic-release.gitbook.io/semantic-release/#how-does-it-work
161 |
--------------------------------------------------------------------------------
/src/demo/SmartImage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |