Skip to content

Commit 0422a1a

Browse files
committed
Add instructions about order mutation and some notes
1 parent a36c591 commit 0422a1a

File tree

1 file changed

+92
-13
lines changed

1 file changed

+92
-13
lines changed

README.md

Lines changed: 92 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,7 @@ You can pass an object of options, in order to affect the behavior of the direct
8989

9090
```html
9191
<template>
92-
<h1>My Component</h1>
93-
94-
<div v-sortable="{ disabled: false, options: { animation: 250, easing: 'cubic-bezier(1, 0, 0, 1)' }}">
92+
<div v-sortable="{ disabled: false, options: { animation: 250, easing: 'cubic-bezier(1, 0, 0, 1)' } }">
9593
<div>a</div>
9694
<div>b</div>
9795
<div>c</div>
@@ -121,16 +119,10 @@ As well, you can listen to any native Sortable event.
121119

122120
```html
123121
<template>
124-
<h1>My Component</h1>
125-
126-
<div
127-
v-sortable
128-
@ready="onReady"
129-
@end="onOrderChange"
130-
>
131-
<div data-id="1">a</div>
132-
<div data-id="2">b</div>
133-
<div data-id="3">c</div>
122+
<div v-sortable @ready="onReady" @end="onOrderChange">
123+
<div>a</div>
124+
<div>b</div>
125+
<div>c</div>
134126
</div>
135127
</template>
136128

@@ -151,6 +143,93 @@ export default {
151143
```
152144

153145

146+
## Order mutation
147+
148+
This wrapper only impacts the actual DOM order, **it does not mutate the data order**.
149+
This avoids a lot of overhead in the code, and give you the full control on your data.
150+
151+
It is really simple to change the order in your data after an item is dropped:
152+
```html
153+
<template>
154+
<div v-sortable @end="onOrderChange">
155+
<div v-for="item in items">
156+
{{ item }}
157+
</div>
158+
</div>
159+
160+
<span>Items data: {{ items }}</span>
161+
</template>
162+
163+
<script>
164+
export default {
165+
data() {
166+
return {
167+
items: [ "a", "b", "c" ]
168+
}
169+
},
170+
171+
methods: {
172+
onOrderChange(event) {
173+
// Remove item from old index
174+
let item = this.items.splice(event.oldIndex, 1)[0];
175+
176+
// Insert at new index
177+
this.items.splice(event.newIndex, 0, item);
178+
}
179+
}
180+
};
181+
</script>
182+
```
183+
184+
185+
## Notes
186+
187+
It is highly recommended to set a **key on the children items**, to help Sortable track the DOM:
188+
189+
```html
190+
<template>
191+
<div v-sortable>
192+
<div key="a">a</div>
193+
<div key="b">b</div>
194+
<div key="c">c</div>
195+
</div>
196+
</template>
197+
```
198+
199+
In the same way, if you use the `group` option, it is highly recommended to set a **key on the parent** itself. Otherwise the DOM managed by Sortable can become out-of-sync with the actual data state. I have noticed this helps a lot when using Sortable with complex components.
200+
The key must be based on the number of items the parent contains. This will force a re-render when an item is added / removed, and make Sortable re-initialize and start from a clean state every time. This may seem a bit hacky, but it's the only way to keep a consistant behavior.
201+
202+
```html
203+
<template>
204+
<h1>Foo</h1>
205+
206+
<div v-sortable="{ options: { group: 'items' } }" @end="onOrderChange" :key="fooItems.length">
207+
<div v-for="item in fooItems" :key="item">
208+
{{ item }}
209+
</div>
210+
</div>
211+
212+
<h1>Bar</h1>
213+
214+
<div v-sortable="{ options: { group: 'items' } }" @end="onOrderChange" :key="barItems.length">
215+
<div v-for="item in barItems" :key="item">
216+
{{ item }}
217+
</div>
218+
</div>
219+
</template>
220+
221+
<script>
222+
export default {
223+
methods: {
224+
onOrderChange(event) {
225+
// Mutate fooItems and barItems
226+
}
227+
}
228+
};
229+
</script>
230+
```
231+
232+
154233
## License
155234

156235
vue3-sortablejs is released under the MIT License. See the bundled LICENSE file for details.

0 commit comments

Comments
 (0)