vue-virtual-scroll-list
Version:
A vue component support big amount data list with high scroll performance.
237 lines (175 loc) • 13.8 kB
Markdown
<p>
<a href="https://travis-ci.org/tangbc/vue-virtual-scroll-list">
<img alt="Travis CI Status" src="https://travis-ci.org/tangbc/vue-virtual-scroll-list.svg?branch=master"/>
</a>
<a href="https://codecov.io/gh/tangbc/vue-virtual-scroll-list">
<img alt="Code Coverage" src="https://codecov.io/gh/tangbc/vue-virtual-scroll-list/branch/master/graph/badge.svg"/>
</a>
<a href="https://npmjs.com/package/vue-virtual-scroll-list">
<img alt="NPM downloads" src="https://img.shields.io/npm/dm/vue-virtual-scroll-list.svg">
</a>
<a href="http://packagequality.com/#?package=vue-virtual-scroll-list">
<img alt="Package quality" src="https://npm.packagequality.com/shield/vue-virtual-scroll-list.svg">
</a>
<a href="https://npmjs.com/package/vue-virtual-scroll-list">
<img alt="NPM version" src="https://img.shields.io/npm/v/vue-virtual-scroll-list.svg"/>
</a>
<a href="https://vuejs.org/">
<img alt="Vue version" src="https://img.shields.io/badge/vue-%3E=2.3.0-brightgreen.svg"/>
</a>
<a href="https://opensource.org/licenses/MIT">
<img alt="License" src="https://img.shields.io/npm/l/vue-virtual-scroll-list.svg">
</a>
</p>
## Table of contents
* [Advantages](#advantages)
* [Live demos](#live-demos)
* [How it works](#how-it-works)
* [Simple usage](#simple-usage)
* [vfor-mode](#vfor-mode)
* [item-mode](#item-mode)
* [variable height](#variable-height)
* [Performance comparison](#performance-comparison)
* [Build time wasted](#build-time-wasted)
* [Total memory used](#total-memory-used)
* [Attentions](#attentions)
* [**Props type**](#props-type)
* [Public methods](#public-methods)
* [Contributions](#contributions)
* [Changelogs](#changelogs)
## Advantages
* Items are independent.
* Tiny and very easy to use.
* Big data list with high performance.
## Live demos
* [Build 100,000 items with vfor-mode](https://tangbc.github.io/vue-virtual-scroll-list/demos/vfor-mode).
* [Build 100,000 items with item-mode](https://tangbc.github.io/vue-virtual-scroll-list/demos/item-mode).
* [Build 100,000 items with variable height](https://tangbc.github.io/vue-virtual-scroll-list/demos/variable-height).
The main difference between `item-mode` and `vfor-mode` is that: `item-mode` make a higher performance but not very convenient to handle changing data frequently; however, `vfor-mode` is just the opposite.
Besides, you can also compare the experience which without using virtual-list here: [without-virtual-list](https://tangbc.github.io/vue-virtual-scroll-list/demos/without-virtual-list).
## How it works
<img src="https://tangbc.github.io/github-images/virtual-scroll-list-how-works.gif">
## Simple usage
```console
npm install vue-virtual-scroll-list --save
```
### vfor-mode
All you need to care about is only data!
```vue
<template>
<div>
<virtual-list :size="40" :remain="8">
<item v-for="item of items" :key="item.id" />
</virtual-list>
</div>
</template>
<script>
import item from '../item.vue'
import virtualList from 'vue-virtual-scroll-list'
export default {
data () {
return {
items: [ {id: 1}, {id: 2}, {id: 3}, ... ]
}
},
components: { item, 'virtual-list': virtualList }
}
</script>
```
### item-mode
This mode can save a considerable amount of memory and performance. Props `item`, `itemcount` and `itemprops` are both required, you don't need put `<item/>` with a v-for directive inside `virtual-list`, just assign it as prop `item`:
```vue
<template>
<div>
<virtual-list :size="40" :remain="8"
:item="item"
:itemcount="100000"
:itemprops="getItemprops"
/>
</div>
</template>
<script>
import itemComponent from '../item.vue'
import virtualList from 'vue-virtual-scroll-list'
export default {
data () {
return {
item: itemComponent,
}
},
methods: {
getItemprops (itemIndex) {
const itemProps = getItemProp(itemIndex)
return {
// <item/> will render with itemProps.
// https://vuejs.org/v2/guide/render-function.html#createElement-Arguments
props: itemProps
}
}
},
components: { 'virtual-list': virtualList }
}
</script>
```
Whenever you want to change any item data from list in this mode, you need call public method `forceRender()` after source data change. Increase or decrease items, you need to keep `itemcount` and call `forceRender()` together.
### variable height
Using variable height, props `remain` and `size` is still required. All the index variable height and scroll offset will be cached by virtual-list after the binary-search calculate, if you want to change anyone `<item/>` height from data, you need call public method `updateVariable(index)` to clear the offset cache.
If you assign `variable` as `true`, **do not** set inline style height inside `<item/>` component, you **must** set inline style height on `<item/>` component outside directly, such as:
```vue
<template>
<div>
<virtual-list :size="40" :remain="8" :variable="true">
<item v-for="item of items" :key="item.id" :style="{ height: item.height + 'px' }" />
</virtual-list>
</div>
</template>
```
**More use ways or getting start you can refer to these clearly [demos](https://github.com/tangbc/vue-virtual-scroll-list/tree/master/demos) or [test suites](https://github.com/tangbc/vue-virtual-scroll-list/tree/master/test).**
## Performance comparison
According to the demos above, here are lists of approximate statistics:
#### Build time wasted
| Build amount | item-mode | vfor-mode | *without virtual list* |
|-------------:|-----------|-----------|------------------------|
| **1,000** | 8 ms | 35 ms | 220 ms |
| **10,000** | 10 ms | 170 ms | 1500 ms |
| **100,000** | 20 ms | 1300 ms | Browser crash! |
#### Total memory used
| Build amount | item-mode | vfor-mode | *without virtual list* |
|-------------:|-----------|-----------|------------------------|
| **1,000** | 10 MB | 80 MB | 200 MB |
| **10,000** | 25 MB | 120 MB | 220 MB |
| **100,000** | 55 MB | 550 MB | Browser crash! |
## Attentions
* Must assign the `:key` property on `<item>` component or dom frag with `v-for` directive.
* Consider using `box-sizing: border-box` on `<item>` if you want absolutely correct scroll height.
## Props type
<img height="256" src="https://tangbc.github.io/github-images/vitual-scroll-list-prop-type.png">
| Prop | Type | Required | Description |
|-----------|---------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| size | Number | ✓ | Each list item height, in variable height, this prop just use to calculate the virtual-list outside container viewport fixed height. |
| remain | Number | ✓ | How many items should be shown in virtual-list viewport, so `size` and `remain` determine the outside container viewport height (`size × remian`). |
| bench | Number | * | Default value is equal to `remain`, unreached items count, not show in virtual-list viewport but exist in real DOM, the larger the bench, the higher the scroll performance will achieved. |
| start | Number | * | Default value is `0`, the initial scroll start index. It must be integer and in the range of list index, if invalid there will be effected as `0` or the last one. |
| offset | Number | * | Default value is `0`, the initial scroll offset. If both `start` and `offset` are assigned at initialization, `start` is preferred. |
| debounce | Number | * | It's disabled by default, milliseconds of using `debounce` function to ensure scroll event doesn't fire so often that it bricks browser performance. |
| rtag | String | * | Default value is `div`, the virtual-list root element tag name, in all cases it's style is set to `display: block;` |
| wtag | String | * | Default value is `div`, the virtual-list item wrapper element tag name, in all cases it's style is set to `display: block;` |
| wclass | String | * | Default is no classname, the virtual-list item wrapper element class, if assign this prop, you better **not** to change it's [CSS box model](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model). |
| pagemode | Boolean | * | Let virtual-list scroll with page viewport. |
| totop | Function | * | Called when virtual-list is scrolled to top, no param. |
| tobottom | Function | * | Called when virtual-list is scrolled to bottom, no param. |
| onscroll | Function | * | Called when virtual-list is scrolling, with param: [`(event, data)`](https://github.com/tangbc/vue-virtual-scroll-list/releases/tag/v1.1.7). |
| variable | Function or Boolean | * | Used in variable height, if assign `Function`, this prop is a variable height getter function which is called with param: `(index)` when each item is ready to be calculated; if assign `Boolean`, virtual-list will get each item variable height by it's inline style height automatic. |
| item | Component | * | Using in `item-mode`, list item vue component. |
| itemcount | Number | * | Using in `item-mode`, list data total counts. |
| itemprops | Function | * | Using in `item-mode`, a function call when each item is going to be rendered. |
## Public methods
Here are some usefull public methods you can call via [`ref`](https://vuejs.org/v2/guide/components-edge-cases.html#Accessing-Child-Component-Instances-amp-Child-Elements):
* `forceRender()`: force render virtual-list if you need or make it refresh.
* `updateVariable(index)`: update item height by index in variable height list.
## Contributions
Welcome to improve vue-virtual-scroll-list with any issue, pull request or code review.
## Changelogs
Maintain and update occasionally, for changes see [release](https://github.com/tangbc/vue-virtual-scroll-list/releases).
## License
[MIT License](https://github.com/tangbc/vue-virtual-scroll-list/blob/master/LICENSE)