packages/integrations/useSortable/index.md
Wrapper for sortable.
For more information on what options can be passed, see Sortable.options in the Sortable documentation.
::: warning
Currently, useSortable only implements drag-and-drop sorting for a single list.
:::
npm i sortablejs@^1
<script setup lang="ts">
import { useSortable } from '@vueuse/integrations/useSortable'
import { shallowRef, useTemplateRef } from 'vue'
const el = useTemplateRef('el')
const list = shallowRef([{ id: 1, name: 'a' }, { id: 2, name: 'b' }, { id: 3, name: 'c' }])
useSortable(el, list)
</script>
<template>
<div ref="el">
<div v-for="item in list" :key="item.id">
{{ item.name }}
</div>
</div>
</template>
<script setup lang="ts">
import { useSortable } from '@vueuse/integrations/useSortable'
import { shallowRef, useTemplateRef } from 'vue'
const el = useTemplateRef('el')
const list = shallowRef([{ id: 1, name: 'a' }, { id: 2, name: 'b' }, { id: 3, name: 'c' }])
const animation = 200
const { option } = useSortable(el, list, {
handle: '.handle',
// or option set
// animation
})
// You can use the option method to set and get the option of Sortable
option('animation', animation)
// option('animation') // 200
</script>
<template>
<div ref="el">
<div v-for="item in list" :key="item.id">
<span>{{ item.name }}</span>
<span class="handle">*</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useSortable } from '@vueuse/integrations/useSortable'
import { shallowRef } from 'vue'
const list = shallowRef([{ id: 1, name: 'a' }, { id: 2, name: 'b' }, { id: 3, name: 'c' }])
useSortable('#dv', list)
</script>
<template>
<div id="dv">
<div v-for="item in list" :key="item.id">
<span>{{ item.name }}</span>
</div>
</div>
</template>
<script setup lang="ts">
import { UseSortable } from '@vueuse/integrations/useSortable/component'
import { shallowRef } from 'vue'
const list = shallowRef([
{ id: 1, name: 'a' },
{ id: 2, name: 'b' },
{ id: 3, name: 'c' },
])
</script>
<template>
<UseSortable v-model="list" as="ol" :options="{ animation: 150 }">
<li v-for="item in list" :key="item.id">
{{ item.name }}
</li>
</UseSortable>
</template>
You can also access the helper functions like start, stop, and option from the slot scope:
<template>
<UseSortable v-slot="{ stop, start }" v-model="list">
<button @click="stop()">
Stop Sorting
</button>
<button @click="start()">
Start Sorting
</button>
<div v-for="item in list" :key="item.id">
{{ item.name }}
</div>
</UseSortable>
</template>
| Property | Description |
|---|---|
start | Initialize the Sortable instance (called automatically on mount) |
stop | Destroy the Sortable instance |
option | Get or set Sortable options at runtime |
const { start, stop, option } = useSortable(el, list)
// Stop sorting
stop()
// Start sorting again
start()
// Get/set options
option('animation', 200) // set
const animation = option('animation') // get
Use the watchElement option to automatically reinitialize Sortable when the element changes (useful with v-if).
import { useSortable } from '@vueuse/integrations/useSortable'
useSortable(el, list, {
watchElement: true, // auto-reinitialize when element changes
})
If you want to handle the onUpdate yourself, you can pass in onUpdate parameters, and we also exposed a function to move the item position.
import { moveArrayElement, useSortable } from '@vueuse/integrations/useSortable'
useSortable(el, list, {
onUpdate: (e) => {
// do something
moveArrayElement(list, e.oldIndex, e.newIndex, e)
// nextTick required here as moveArrayElement is executed in a microtask
// so we need to wait until the next tick until that is finished.
nextTick(() => {
/* do something */
})
}
})
The following helper functions are also exported:
| Function | Description |
|---|---|
moveArrayElement(list, from, to, event?) | Move an element in an array from one index to another |
insertNodeAt(parent, element, index) | Insert a DOM node at a specific index |
removeNode(node) | Remove a DOM node from its parent |