UNPKG

14 kBMarkdownView Raw
1<p align="center"><img width="140"src="https://raw.githubusercontent.com/SortableJS/Vue.Draggable/master/logo.svg?sanitize=true"></p>
2<h1 align="center">Vue.Draggable</h1>
3
4[![CircleCI](https://circleci.com/gh/SortableJS/Vue.Draggable.svg?style=shield)](https://circleci.com/gh/SortableJS/Vue.Draggable)
5[![Coverage](https://codecov.io/gh/SortableJS/Vue.Draggable/branch/master/graph/badge.svg)](https://codecov.io/gh/SortableJS/Vue.Draggable)
6[![codebeat badge](https://codebeat.co/badges/7a6c27c8-2d0b-47b9-af55-c2eea966e713)](https://codebeat.co/projects/github-com-sortablejs-vue-draggable-master)
7[![GitHub open issues](https://img.shields.io/github/issues/SortableJS/Vue.Draggable.svg)](https://github.com/SortableJS/Vue.Draggable/issues?q=is%3Aopen+is%3Aissue)
8[![npm download](https://img.shields.io/npm/dt/vuedraggable.svg?maxAge=30)](https://www.npmjs.com/package/vuedraggable)
9[![npm download per month](https://img.shields.io/npm/dm/vuedraggable.svg)](https://www.npmjs.com/package/vuedraggable)
10[![npm version](https://img.shields.io/npm/v/vuedraggable.svg)](https://www.npmjs.com/package/vuedraggable)
11[![MIT License](https://img.shields.io/github/license/SortableJS/Vue.Draggable.svg)](https://github.com/SortableJS/Vue.Draggable/blob/master/LICENSE)
12
13
14Vue component (Vue.js 2.0) or directive (Vue.js 1.0) allowing drag-and-drop and synchronization with view model array.
15
16Based on and offering all features of [Sortable.js](https://github.com/RubaXa/Sortable)
17
18## Demo
19
20![demo gif](https://raw.githubusercontent.com/SortableJS/Vue.Draggable/master/example.gif)
21
22## Live Demos
23
24https://sortablejs.github.io/Vue.Draggable/
25
26https://david-desmaisons.github.io/draggable-example/
27
28## Features
29
30* Full support of [Sortable.js](https://github.com/RubaXa/Sortable) features:
31 * Supports touch devices
32 * Supports drag handles and selectable text
33 * Smart auto-scrolling
34 * Support drag and drop between different lists
35 * No jQuery dependency
36* Keeps in sync HTML and view model list
37* Compatible with Vue.js 2.0 transition-group
38* Cancellation support
39* Events reporting any changes when full control is needed
40* Reuse existing UI library components (such as [vuetify](https://vuetifyjs.com), [element](http://element.eleme.io/), or [vue material](https://vuematerial.io) etc...) and make them draggable using `tag` and `componentData` props
41
42## Backers
43
44 <a href="https://flatlogic.com/admin-dashboards">
45 <img width="190" style="margin-top: 10px;" src="https://flatlogic.com/assets/logo-d9e7751df5fddd11c911945a75b56bf72bcfe809a7f6dca0e32d7b407eacedae.svg">
46 </a>
47
48Admin Dashboard Templates made with Vue, React and Angular.
49
50
51## Donate
52
53Find this project useful? You can buy me a :coffee: or a :beer:
54
55[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=GYAEKQZJ4FQT2&currency_code=USD&source=url)
56
57
58## Installation
59
60### With npm or yarn
61
62```bash
63yarn add vuedraggable
64
65npm i -S vuedraggable
66```
67
68**Beware it is vuedraggable for Vue 2.0 and not vue-draggable which is for version 1.0**
69
70### with direct link
71```html
72
73<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
74<!-- CDNJS :: Sortable (https://cdnjs.com/) -->
75<script src="//cdn.jsdelivr.net/npm/sortablejs@1.8.4/Sortable.min.js"></script>
76<!-- CDNJS :: Vue.Draggable (https://cdnjs.com/) -->
77<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.20.0/vuedraggable.umd.min.js"></script>
78
79```
80
81[cf example section](https://github.com/SortableJS/Vue.Draggable/tree/master/example)
82
83## For Vue.js 2.0
84
85Use draggable component:
86
87### Typical use:
88``` html
89<draggable v-model="myArray" group="people" @start="drag=true" @end="drag=false">
90 <div v-for="element in myArray" :key="element.id">{{element.name}}</div>
91</draggable>
92```
93.vue file:
94``` js
95 import draggable from 'vuedraggable'
96 ...
97 export default {
98 components: {
99 draggable,
100 },
101 ...
102```
103
104### With `transition-group`:
105``` html
106<draggable v-model="myArray">
107 <transition-group>
108 <div v-for="element in myArray" :key="element.id">
109 {{element.name}}
110 </div>
111 </transition-group>
112</draggable>
113```
114
115Draggable component should directly wrap the draggable elements, or a `transition-component` containing the draggable elements.
116
117
118### With footer slot:
119``` html
120<draggable v-model="myArray" draggable=".item">
121 <div v-for="element in myArray" :key="element.id" class="item">
122 {{element.name}}
123 </div>
124 <button slot="footer" @click="addPeople">Add</button>
125</draggable>
126```
127### With header slot:
128``` html
129<draggable v-model="myArray" draggable=".item">
130 <div v-for="element in myArray" :key="element.id" class="item">
131 {{element.name}}
132 </div>
133 <button slot="header" @click="addPeople">Add</button>
134</draggable>
135```
136
137### With Vuex:
138
139```html
140<draggable v-model='myList'>
141```
142
143```javascript
144computed: {
145 myList: {
146 get() {
147 return this.$store.state.myList
148 },
149 set(value) {
150 this.$store.commit('updateList', value)
151 }
152 }
153}
154```
155
156
157### Props
158#### value
159Type: `Array`<br>
160Required: `false`<br>
161Default: `null`
162
163Input array to draggable component. Typically same array as referenced by inner element v-for directive.<br>
164This is the preferred way to use Vue.draggable as it is compatible with Vuex.<br>
165It should not be used directly but only though the `v-model` directive:
166```html
167<draggable v-model="myArray">
168```
169
170#### list
171Type: `Array`<br>
172Required: `false`<br>
173Default: `null`
174
175Alternative to the `value` prop, list is an array to be synchronized with drag-and-drop.<br>
176The main difference is that `list` prop is updated by draggable component using splice method, whereas `value` is immutable.<br>
177**Do not use in conjunction with value prop.**
178
179#### All sortable options
180New in version 2.19
181
182Sortable options can be set directly as vue.draggable props since version 2.19.
183
184This means that all [sortable option](https://github.com/RubaXa/Sortable#options) are valid sortable props with the notable exception of all the method starting by "on" as draggable component expose the same API via events.
185
186kebab-case propery are supported: for example `ghost-class` props will be converted to `ghostClass` sortable option.
187
188Example setting handle, sortable and a group option:
189```HTML
190<draggable
191 v-model="list"
192 handle=".handle"
193 :group="{ name: 'people', pull: 'clone', put: false }"
194 ghost-class="ghost"
195 :sort="false"
196 @change="log"
197 >
198 <!-- -->
199</draggable>
200```
201
202#### tag
203Type: `String`<br>
204Default: `'div'`
205
206HTML node type of the element that draggable component create as outer element for the included slot.<br>
207It is also possible to pass the name of vue component as element. In this case, draggable attribute will be passed to the create component.<br>
208See also [componentData](#componentdata) if you need to set props or event to the created component.
209
210#### clone
211Type: `Function`<br>
212Required: `false`<br>
213Default: `(original) => { return original;}`<br>
214
215Function called on the source component to clone element when clone option is true. The unique argument is the viewModel element to be cloned and the returned value is its cloned version.<br>
216By default vue.draggable reuses the viewModel element, so you have to use this hook if you want to clone or deep clone it.
217
218#### move
219Type: `Function`<br>
220Required: `false`<br>
221Default: `null`<br>
222
223If not null this function will be called in a similar way as [Sortable onMove callback](https://github.com/RubaXa/Sortable#move-event-object).
224Returning false will cancel the drag operation.
225
226```javascript
227function onMoveCallback(evt, originalEvent){
228 ...
229 // return false; — for cancel
230}
231```
232evt object has same property as [Sortable onMove event](https://github.com/RubaXa/Sortable#move-event-object), and 3 additional properties:
233 - `draggedContext`: context linked to dragged element
234 - `index`: dragged element index
235 - `element`: dragged element underlying view model element
236 - `futureIndex`: potential index of the dragged element if the drop operation is accepted
237 - `relatedContext`: context linked to current drag operation
238 - `index`: target element index
239 - `element`: target element view model element
240 - `list`: target list
241 - `component`: target VueComponent
242
243HTML:
244```HTML
245<draggable :list="list" :move="checkMove">
246```
247javascript:
248```javascript
249checkMove: function(evt){
250 return (evt.draggedContext.element.name!=='apple');
251}
252```
253See complete example: [Cancel.html](https://github.com/SortableJS/Vue.Draggable/blob/master/examples/Cancel.html), [cancel.js](https://github.com/SortableJS/Vue.Draggable/blob/master/examples/script/cancel.js)
254
255#### componentData
256Type: `Object`<br>
257Required: `false`<br>
258Default: `null`<br>
259
260This props is used to pass additional information to child component declared by [tag props](#tag).<br>
261Value:
262* `props`: props to be passed to the child component
263* `attrs`: attrs to be passed to the child component
264* `on`: events to be subscribe in the child component
265
266Example (using [element UI library](http://element.eleme.io/#/en-US)):
267```HTML
268<draggable tag="el-collapse" :list="list" :component-data="getComponentData()">
269 <el-collapse-item v-for="e in list" :title="e.title" :name="e.name" :key="e.name">
270 <div>{{e.description}}</div>
271 </el-collapse-item>
272</draggable>
273```
274```javascript
275methods: {
276 handleChange() {
277 console.log('changed');
278 },
279 inputChanged(value) {
280 this.activeNames = value;
281 },
282 getComponentData() {
283 return {
284 on: {
285 change: this.handleChange,
286 input: this.inputChanged
287 },
288 attrs:{
289 wrap: true
290 },
291 props: {
292 value: this.activeNames
293 }
294 };
295 }
296 }
297```
298
299### Events
300
301* Support for Sortable events:
302
303 `start`, `add`, `remove`, `update`, `end`, `choose`, `unchoose`, `sort`, `filter`, `clone`<br>
304 Events are called whenever onStart, onAdd, onRemove, onUpdate, onEnd, onChoose, onUnchoose, onSort, onClone are fired by Sortable.js with the same argument.<br>
305 [See here for reference](https://github.com/RubaXa/Sortable#event-object-demo)
306
307 Note that SortableJS OnMove callback is mapped with the [move prop](https://github.com/SortableJS/Vue.Draggable/blob/master/README.md#move)
308
309HTML:
310```HTML
311<draggable :list="list" @end="onEnd">
312```
313
314* change event
315
316 `change` event is triggered when list prop is not null and the corresponding array is altered due to drag-and-drop operation.<br>
317 This event is called with one argument containing one of the following properties:
318 - `added`: contains information of an element added to the array
319 - `newIndex`: the index of the added element
320 - `element`: the added element
321 - `removed`: contains information of an element removed from to the array
322 - `oldIndex`: the index of the element before remove
323 - `element`: the removed element
324 - `moved`: contains information of an element moved within the array
325 - `newIndex`: the current index of the moved element
326 - `oldIndex`: the old index of the moved element
327 - `element`: the moved element
328
329### Slots
330
331Limitation: neither header or footer slot works in conjunction with transition-group.
332
333#### Header
334Use the `header` slot to add none-draggable element inside the vuedraggable component.
335Important: it should be used in conjunction with draggable option to tag draggable element.
336Note that header slot will always be added before the default slot regardless its position in the template.
337Ex:
338
339``` html
340<draggable v-model="myArray" draggable=".item">
341 <div v-for="element in myArray" :key="element.id" class="item">
342 {{element.name}}
343 </div>
344 <button slot="header" @click="addPeople">Add</button>
345</draggable>
346```
347
348#### Footer
349Use the `footer` slot to add none-draggable element inside the vuedraggable component.
350Important: it should be used in conjunction with draggable option to tag draggable elements.
351Note that footer slot will always be added after the default slot regardless its position in the template.
352Ex:
353
354``` html
355<draggable v-model="myArray" draggable=".item">
356 <div v-for="element in myArray" :key="element.id" class="item">
357 {{element.name}}
358 </div>
359 <button slot="footer" @click="addPeople">Add</button>
360</draggable>
361```
362 ### Gotchas
363
364 - Vue.draggable children should always map the list or value prop using a v-for directive
365 * You may use [header](https://github.com/SortableJS/Vue.Draggable#header) and [footer](https://github.com/SortableJS/Vue.Draggable#footer) slot to by-pass this limitation.
366
367 - Children elements inside v-for should be keyed as any element in Vue.js. Be carefull to provide revelant key values in particular:
368 * typically providing array index as keys won't work as key should be linked to the items content
369 * cloned elements should provide updated keys, it is doable using the [clone props](#clone) for example
370
371
372 ### Example
373 * [Clone](https://sortablejs.github.io/Vue.Draggable/#/custom-clone)
374 * [Handle](https://sortablejs.github.io/Vue.Draggable/#/handle)
375 * [Transition](https://sortablejs.github.io/Vue.Draggable/#/transition-example-2)
376 * [Nested](https://sortablejs.github.io/Vue.Draggable/#/nested-example)
377 * [Table](https://sortablejs.github.io/Vue.Draggable/#/table-example)
378
379 ### Full demo example
380
381[draggable-example](https://github.com/David-Desmaisons/draggable-example)
382
383## For Vue.js 1.0
384
385[See here](documentation/Vue.draggable.for.ReadME.md)
386
387```
388
\No newline at end of file