Vue Draggable Virtual Scroll List
This `vue-draggable-virtual-scroll-list` package is a Vue 2 component designed to combine the drag-and-drop capabilities of `SortableJS/Vue.Draggable` with the performance benefits of `tangbc/vue-virtual-scroll-list` for rendering large datasets. It allows developers to create sortable lists that efficiently handle a significant number of items by only rendering the visible elements, while still supporting intuitive drag-and-drop interactions. Currently at version 0.0.15, the project appears to be in an early development phase, suggesting potential for rapid changes. Its primary differentiation lies in offering a pre-integrated solution for two common UI challenges in Vue 2: managing large lists and enabling sortability, bypassing the need for manual integration of these complex libraries. It explicitly lists Vue 2.6.14 or higher as a peer dependency, firmly placing it within the Vue 2 ecosystem.
Common errors
-
Failed to resolve component: DraggableVirtualList
cause The component was not properly imported or registered in your Vue instance.fixEnsure you have `import { DraggableVirtualList } from 'vue-draggable-virtual-scroll-list'` and added it to your Vue instance's `components` option: `components: { DraggableVirtualList }`. -
Cannot read property 'getBoundingClientRect' of null (or similar errors related to DOM elements not found or inconsistent rendering)
cause Often occurs when the underlying virtual list or draggable library fails to access DOM elements due to incorrect item keys, dynamic rendering issues, or a mutable list being directly manipulated outside of `v-model` setters.fixVerify that each item in your `v-model` array has a unique `id` property and that `:data-key` is correctly set to this property (e.g., `:data-key="'id'"`). Ensure your `data-component` structure is stable and not causing unexpected re-renders or DOM manipulation. -
Drag-and-drop does not work, items are not reordered, or drag ghosts appear incorrectly.
cause Usually caused by misconfiguration of the `vuedraggable` part of the component, such as incorrect `v-model` binding, missing unique `data-key`, or issues with the structure/props of your `data-component`.fixCheck that your `v-model` is correctly bound to your data array, `:data-key` points to a unique identifier, and your `data-component` correctly exposes the `source` prop for individual items to facilitate reordering.
Warnings
- breaking This package is currently in an early development phase (v0.0.15) and does not strictly adhere to semantic versioning. Any minor version update may introduce breaking changes without prior notice.
- gotcha This component is built specifically for Vue 2 applications and is incompatible with Vue 3 due to fundamental changes in the Vue API and its underlying dependencies (`vuedraggable` and `vue-virtual-scroll-list` each have Vue 3 specific versions).
- gotcha The component requires a `:data-key` prop which must correspond to a unique identifier on each item in your data array. Failure to provide a unique key can lead to inconsistent rendering or incorrect drag-and-drop behavior.
- gotcha Both `v-model` and `:data-sources` props are used to bind the list data. While `v-model` is primarily for updating the list order after a drag operation, `:data-sources` is used by the underlying virtual list for rendering. Ensure both are correctly bound to the same data array to avoid inconsistencies.
- gotcha Optimal performance of the virtual scroll list depends heavily on correctly setting the `:size` (estimated height of each item) and `:keeps` (number of items to keep rendered outside the viewport) props. Incorrect values can lead to choppy scrolling, rendering issues, or excessive DOM elements.
Install
-
npm install vue-draggable-virtual-scroll-list -
yarn add vue-draggable-virtual-scroll-list -
pnpm add vue-draggable-virtual-scroll-list
Imports
- DraggableVirtualList
const DraggableVirtualList = require('vue-draggable-virtual-scroll-list');import { DraggableVirtualList } from 'vue-draggable-virtual-scroll-list'; - Item
const Item = { /* ... */ };
Quickstart
import Vue from 'vue';
import { DraggableVirtualList } from 'vue-draggable-virtual-scroll-list';
// Define the individual item component
const Item = {
props: {
source: {
type: Object,
default: () => ({}),
},
},
template: `
<div class="phrase" :key="source.id" style="padding: 10px; border-bottom: 1px solid #eee; background-color: white;">
{{ source.content }}
</div>
`,
};
new Vue({
el: '#app',
components: {
DraggableVirtualList,
},
data() {
const items = [];
// Generate a large number of items for virtualization demo
for (let i = 0; i < 1000; i++) {
items.push({
id: i,
content: `Item ${i + 1} - Drag me!`, // Example content
});
}
return {
items: items,
Item: Item, // Pass the local Item component to the DraggableVirtualList
};
},
template: `
<div id="app">
<h2>Draggable Virtual List Example</h2>
<p>Drag and drop items in this list. It efficiently handles 1000 items.</p>
<draggable-virtual-list
class="phrase-list"
v-model="items"
:size="50" // Estimated height of each item in pixels
:keeps="20" // Number of items to keep rendered outside the viewport
:data-key="'id'" // Unique key for each item in the data source
:data-sources="items" // Data source for the virtual list
:data-component="Item" // Component to render each item
style="height: 400px; overflow-y: auto; border: 1px solid #ccc;"
>
</draggable-virtual-list>
</div>
`,
});