Vue.Draggable

Vue 2 drag-and-drop component built on Sortable.js for reorderable lists

Library
npm
v2.24.3
20,552 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
53 /100 Fair
Development Activity 0
Maintenance 32
Community 80
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
67 /100 Good
Architecture 68
Code Quality 62
Innovation 60
Learning Curve 78

Vue.Draggable wraps the battle-tested Sortable.js library in a native Vue 2 component, letting you turn any v-for list into a drag-and-drop reorderable list with a single <draggable> wrapper and a v-model binding. It keeps the DOM and the underlying view-model array in sync automatically, so reordering, moving items between lists, and removing items all flow back into your application state without manual DOM manipulation.

Because it is a thin, faithful wrapper around Sortable.js, it inherits that library’s full feature set — touch support, drag handles, cross-list dragging, auto-scroll, and animation — while exposing them as idiomatic Vue props and events. It also plays well with transition-group for animated reordering and can wrap third-party component libraries (Vuetify, Element UI, Vue Material) via the tag and componentData props, making it a common choice for kanban boards, sortable form builders, and admin dashboards built on Vue 2.

What You Get

  • A <draggable> component that wraps any list of elements and makes them sortable via drag-and-drop
  • Two-way binding via v-model (immutable) or list (mutated via splice) to keep your data array in sync with the UI
  • Full pass-through of Sortable.js options (handles, groups, animation, ghost classes) as component props
  • Cross-list dragging support via the group option, for moving items between separate draggable lists
  • Compatibility with transition-group for animated insert/remove/reorder transitions
  • Header and footer slots for adding non-draggable elements inside the draggable container

Common Use Cases

  • Kanban-style boards where cards move between draggable columns
  • Reorderable admin lists and settings panels (e.g. reordering menu items or form fields)
  • Sortable form builders that let users drag fields into a desired order
  • To-do list and task manager UIs where items can be reordered or moved between lists
  • Wrapping third-party UI library components (Vuetify, Element UI) to make their rendered items draggable

Under The Hood

Architecture The entire component lives in a single ~485-line src/vuedraggable.js file that wraps a native Sortable instance (from the sortablejs dependency) around a rendered root element. On mount, it instantiates Sortable against its own root DOM node, translating Vue props into Sortable’s option object and re-registering Sortable’s onAdd/onUpdate/onRemove/onEnd callbacks as Vue-emitted events; on data changes it reconciles the underlying array (list via in-place splice, or value immutably via emitted input events) so drag operations performed on the DOM propagate back into the Vue reactivity graph. A small util folder holds helpers for computing child component slots and headers/footers around the draggable region.

Tech Stack Targets Vue 2.x only (a companion project, vue.draggable.next, exists for Vue 3) and depends solely on sortablejs at runtime. The dev toolchain is Vue CLI 3 (@vue/cli-service) with Babel for transpilation, @vue/test-utils plus Jest for testing, and a documentation/example app built with the same Vue CLI service.

Code Quality A tests/unit suite built on @vue/test-utils and Jest covers component behavior (list synchronization, event emission), and the project ships coverage reporting (test:coverage + Codecov) in CI. TypeScript consumers get a hand-written .d.ts declaration file (src/vuedraggable.d.ts) rather than being compiled from TypeScript source, so type accuracy depends on manual upkeep rather than the compiler.

API Design The public surface is intentionally small: a single <draggable> component consumed via v-model (or list), with all of Sortable.js’s native options (handle, group, ghost-class, animation, etc.) passed straight through as kebab-case props — meaning any Sortable.js capability is available without the wrapper needing to re-implement or re-document it. This keeps the API idiomatic to Vue while trading a little discoverability (advanced options are documented in Sortable.js’s own README, not restated here).

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers