useSortable 
Wrapper for sortable.
For more information on what options can be passed, see Sortable.options in the Sortable documentation.
Demo 
Available in the @vueuse/integrations add-on.Install 
bash
npm i sortablejs@^1Usage 
Use template ref 
vue
<script setup lang="ts">
import { useSortable } from '@vueuse/integrations/useSortable'
import { ref } from 'vue'
const el = ref<HTMLElement | null>(null)
const list = ref([{ 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>Use specifies the selector to operate on 
vue
<script setup lang="ts">
import { useSortable } from '@vueuse/integrations/useSortable'
import { ref } from 'vue'
const el = ref<HTMLElement | null>(null)
const list = ref([{ 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>Use a selector to get the root element 
vue
<script setup lang="ts">
import { useSortable } from '@vueuse/integrations/useSortable'
import { ref } from 'vue'
const list = ref([{ 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>Tips 
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.
ts
import { moveArrayElement } from '@vueuse/integrations/useSortable'
useSortable(el, list, {
  onUpdate: (e) => {
    // do something
    moveArrayElement(list.value, e.oldIndex, e.newIndex)
    // nextTick required here as moveArrayElement is executed in a microtas
    // so we need to wait until the next tick until that is finished.
    nextTick(() => {
      /* do something */
    })
  }
})Type Declarations 
typescript
export interface UseSortableReturn {
  /**
   * start sortable instance
   */
  start: () => void
  /**
   * destroy sortable instance
   */
  stop: () => void
  /**
   * Options getter/setter
   * @param name a Sortable.Options property.
   * @param value a value.
   */
  option: (<K extends keyof Sortable.Options>(
    name: K,
    value: Sortable.Options[K],
  ) => void) &
    (<K extends keyof Sortable.Options>(name: K) => Sortable.Options[K])
}
export type UseSortableOptions = Options & ConfigurableDocument
export declare function useSortable<T>(
  selector: string,
  list: MaybeRefOrGetter<T[]>,
  options?: UseSortableOptions,
): UseSortableReturn
export declare function useSortable<T>(
  el: MaybeRefOrGetter<HTMLElement | null | undefined>,
  list: MaybeRefOrGetter<T[]>,
  options?: UseSortableOptions,
): UseSortableReturn
export declare function moveArrayElement<T>(
  list: MaybeRefOrGetter<T[]>,
  from: number,
  to: number,
): voidSource 
Contributors 
Changelog 
v10.8.0 on 2/20/2024a086e - fix: stricter typesv10.6.0 on 11/9/2023v10.4.0 on 8/25/2023v10.2.0 on 6/16/2023v10.0.0-beta.4 on 4/13/20234d757 - feat(types)!: rename MaybeComputedRef to MaybeRefOrGetter0a72b - feat(toValue): rename resolveUnref to toValuev10.0.0-beta.3 on 4/12/2023v10.0.0-beta.0 on 3/14/2023