All Projects → starkwang → Vue Virtual Collection

starkwang / Vue Virtual Collection

Licence: mit
Vue component for efficiently rendering large collection data

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Vue Virtual Collection

React Virtual List
Super simple virtualized list React component
Stars: ✭ 597 (+17.98%)
Mutual labels:  performance, scroll
Pd Select
vue components ,like ios 3D picker style,vue 3d 选择器组件,3D滚轮
Stars: ✭ 101 (-80.04%)
Mutual labels:  vue-components, scroll
Listpool
Optimized allocation free implementation of IList using ArrayPool.
Stars: ✭ 25 (-95.06%)
Mutual labels:  collection, performance
V Bar
The virtual responsive crossbrowser scrollbar component for VueJS 2x
Stars: ✭ 216 (-57.31%)
Mutual labels:  vue-components, scroll
vue-scroll-snap
A super simple Vue component that allows fullscreen and horizontal scroll snapping.
Stars: ✭ 25 (-95.06%)
Mutual labels:  vue-components, scroll
Kubernetes Internals
This is a collection of resources that shed light on the inner workings of Kubernetes
Stars: ✭ 479 (-5.34%)
Mutual labels:  collection
Cassowary
🚀 Modern cross-platform HTTP load-testing tool written in Go
Stars: ✭ 488 (-3.56%)
Mutual labels:  performance
Netfabric.hyperlinq
High performance LINQ implementation with minimal heap allocations. Supports enumerables, async enumerables, arrays and Span<T>.
Stars: ✭ 479 (-5.34%)
Mutual labels:  performance
Nimporter
Compile Nim Extensions for Python On Import!
Stars: ✭ 474 (-6.32%)
Mutual labels:  performance
Motus
Animation library that mimics CSS keyframes when scrolling.
Stars: ✭ 502 (-0.79%)
Mutual labels:  scroll
Nbench
Performance benchmarking and testing framework for .NET applications 📈
Stars: ✭ 495 (-2.17%)
Mutual labels:  performance
Laravel Pjax
A pjax middleware for Laravel
Stars: ✭ 487 (-3.75%)
Mutual labels:  performance
Ubiquity
Ubiquity framework
Stars: ✭ 480 (-5.14%)
Mutual labels:  performance
Android Studio Poet
Generate large Android Studio projects
Stars: ✭ 489 (-3.36%)
Mutual labels:  performance
Vform
A simple way to handle Laravel back-end validation in Vue 2.
Stars: ✭ 477 (-5.73%)
Mutual labels:  vue-components
Watchdoginspector
Shows your current framerate (fps) in the status bar of your iOS app
Stars: ✭ 497 (-1.78%)
Mutual labels:  performance
30 Seconds Of Swift Code
A Swift implementation of 30-seconds-of-code: A curated collection of useful Swift 4 snippets that you can understand in 30 seconds or less.
Stars: ✭ 476 (-5.93%)
Mutual labels:  collection
Cloud Design Patterns
Prescriptive Architecture Guidance for Cloud Applications
Stars: ✭ 484 (-4.35%)
Mutual labels:  performance
Bytebuf
Example of how CL133375 can be utilized to mitigate Go escape analysis limitations.
Stars: ✭ 494 (-2.37%)
Mutual labels:  performance
Garie
Open source web performance
Stars: ✭ 484 (-4.35%)
Mutual labels:  performance

vue-virtual-collection

npm version Build Status styled with prettier npm

Vue component for efficiently rendering large collection data. Inspired by react-virtualize.

Demo

Demo

Table of Contents generated with DocToc

Usage

Install

npm i vue-virtual-collection

Import

import Vue from 'vue'
import VirtualCollection from 'vue-virtual-collection'

Vue.use(VirtualCollection)

Use it!

vue-virtual-collection offers two ways of using a VirtualCollection.

Default Usage

The standard way of using a VirtualCollection is to to pass the entire collection of items to it as a single group. This is suitable for most cases, especially if all the items in the collection are either very similar or very different from one another.

In the sample below, the collection is instantiated as an Array and passed directly to the VirtualCollection in that form.

<template>
    <div>
        <VirtualCollection
            :cellSizeAndPositionGetter="cellSizeAndPositionGetter"
            :collection="items"
            :height="500"
            :width="330"
        >
            <div slot="cell" slot-scope="props">{{props.data}}</div>
        </VirtualCollection>
    </div>
</template>

<script>
    export default {
        data () {
            return {
                /**
                 * This will create 1000 items like:
                 * [
                 *   { data: '#0' },
                 *   { data: '#1' },
                 *   ...
                 *   { data: '#999' }
                 * ]
                 */
                items: Array.from({length: 1000}, (_, index) => ({ data: '#' + index }))
            }
        },
        methods: {
            cellSizeAndPositionGetter(item, index) {
                // compute size and position
                return {
                    width: 100,
                    height: 150,
                    x: (index % 2) * 110,
                    y: parseInt(index / 2) * 160
                }
            }
        }
    }
</script>

Item Grouping

Item grouping is an optional feature that can be used to potentially improve performance, and is ideally suited to cases where the collection of items to render are logically divisable into a small number of different categories that may be updated, added or removed at different rates.

Instead of passing the entire collection as an array to the VirtualCollection, the collection is passed as an array of "groups" - objects that each contain a subset of the entire collection's items that should logically be handled the same way.

An example of where this might be appropriate is using VirtualCollection to represent a chess game. In this scenario, there might be separate items within the collection to represent the chessboard tiles and the chess pieces. Chessboard tiles and chess pieces are logically distinct categories of items, and each category would update at different rates; the collection of chessboard tiles would never change after being initially rendered, whereas the collection of pieces would change after every move.

Without grouping, changing the position of a piece (or adding/removing one) would cause everything in the collection to be re-processed and potentially re-rendered, including the chessboard tiles. However, if we pass the pieces and the tiles as separate groups, then VirtualCollection will only reprocess the collection of chess pieces after each turn, and skip reprocessing the chessboard tiles.

<template>
    <div>
        <VirtualCollection
            :cellSizeAndPositionGetter="cellSizeAndPositionGetter"
            :collection="collectionGroups"
            :height="500"
            :width="500"
        >
            <div class="grid-cell" slot="cell" slot-scope="{data}">
                <ChessTile v-if="data.isTile" />
                <ChessPiece v-else />
            </div>
        </VirtualCollection>
    </div>
</template>

<script>
    export default {
        data () {
            return {
                chessTiles: [ { data: { isTile: true } }, /* ... */ ],
                chessPieces: [ { data: { isPiece: true } }, /* ... */ ],
                collectionGroups: [ { group: [] }, { group: [] } ]
            }
        },
        methods: {
            cellSizeAndPositionGetter(item, itemIndex, groupIndex) {
                switch (groupIndex)
                {
                    case 0:
                        // Compute size and position for chessboard tile
                        return { width: 0, height: 0, x: 0, y: 0 }
                    
                    case 1:
                        // Compute size and position for chess piece
                        return { width: 0, height: 0, x: 0, y: 0 }

                    default:
                        throw new Error("Not a tile or piece")
                }
            }
        },
        watch: {
            chessTiles: function (chessTiles) {
                this.collectionGroups[0].group = chessTiles;
            },
            chessPieces: function (chessPieces) {
                this.collectionGroups[1].group = chessPieces
            }
        }
    }
</script>

Props

cellSizeAndPositionGetter

Type: Function

(item: object, index: number) -> ({ height: number, width: number, x: number, y: number })

Required: ✓

Callback responsible for returning size and offset/position information for a given cell

function cellSizeAndPositionGetter(item, index) {
    return {
        width: item.width,
        height: item.height,
        x: item.x,
        y: item.y
    }
}

Alternate usage

If using the item grouping feature, the second parameter is the index of the item within the group it belongs to and a third parameter represents the index of the group within the collection of groups passed to VirtualCollection.

(item: object, itemIndex: number, groupIndex: number) -> ({ height: number, width: number, x: number, y: number })

function cellSizeAndPositionGetter(item, itemIndex, groupIndex) {
    return {
        width: item.width,
        height: item.height,
        x: item.x,
        y: item.y
    }
}

collection

Type: Array

Required: ✓

The data for cells to render. Each object in array must contain a data property, which will be passed into slot scope.

const collection = [
    { data: { text: "#1" } },
    { data: { text: "#2" } },
    { data: { text: "#3" } },
    // ...
]

Alternate usage

If using the item grouping feature, each element of the collection should be an object with a group property representing a group of logically-related items. Each item of each group must contain a data property, which will be passed into slot scope.

const collection = [
    {
        group: [
            { data: { text: "#1" } },
            { data: { text: "#2" } },
            { data: { text: "#3" } },
            // ...
        ]
    },
    {
        group: [
            { data: { text: "#A" } },
            { data: { text: "#B" } },
            { data: { text: "#C" } },
            // ...
        ]
    },
    // ...
]

width

Type: number

Required: ✓

The width of collection viewport

height

Type: number

Required: ✓

The height of collection viewport

scrollToBottomRange

Type: number

Default: undefined

When present the component will emit scrolled-to-bottom-range when the bottom is >= 1 and the number provided. The scrolled-to-bottom will still be fired, and the 2 events will not be emitted at the same time.

containerPaddingBottom

Type: number

Default: 0

Optionally extend the calculated height of the collection container, the affect is apparent padding-bottom

headerSlotHeight

Type: number

Default: 0

When injecting content into the header slot, you should also add the px height of the slot. This ensure items are removed from view at the right time.

sectionSize

Type: number

Default: 300

Optionally override the size of the sections a Collection's cells are split into. This is an advanced option and should only be used for performance tuning purposes.

Events

scrolled-to-top

This event is emitted when the container scrollTop is reduced to 0.

scrolled-to-bottom

This event is emitted when the container scrollTop has reach the bottom.

scrolled-to-bottom-range

This event is emitted only when a scrollToBottomRange value is provided, and is fired when the container is scroller with range of the bottom, the range defined by the said prop.

Slots

header

The header slot allows you to simulate a full-page mode for the virtual-scroller content. By setting the VirtualCollection height and width to be that of the browser window, the header will then sit on top of the scrollable items however will move out of view when the VirtualCollection is scrolled down.

<VirtualCollection
    :cellSizeAndPositionGetter="item => { return { width: item.width, height: item.height, x: item.x, y: item.y }}"
    :collection="items.items"
    :height="items.boxHeight"
    :width="items.boxWidth"
    :containerHeightSpacer="50"
    v-on:scrolled-to-top="scrollTop"
    v-on:scrolled-to-bottom="scrollBottom">
  <template v-slot:header>
    <div>
        This content will sit on top of the scrollable items acting as a header.
    </div>
  </template>
  <div slot="cell" slot-scope="props">
      {{props.data}}
  </div>
</VirtualCollection>

cell

<div slot="cell" slot-scope="yourOwnScope">{{yourOwnScope.data.text}}</div>

The data property in items of collection will be passed into the slot scope.

const collection = [
    { data: { text: "#1" } },
    { data: { text: "#2" } },
    { data: { text: "#3" } },
    // ...
]
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].