听别人说Vue的拖拽库都断代了,我第一个不服
vue-draggable-plus
前言
前段时间偶然翻掘金的过程中发现有人宣传 vue
的拖拽库断代了,那么我也来蹭一下热度。
Sortablejs
Sortablejs
是一个功能强大的 JavaScript
拖拽库,并且提供了 vue
相关的组件 vue-draggable
,并且在 vue3
的前期,提供了 vue-draggable-next
,但是可能由于作者的生活过于繁忙的原因,这个库已经两年没有更新了,在当前 vue3
的版本中并不适用,于是乎本人突发奇想,写了一个 vue-draggable-plus
(其实很久之前就写好了,没有可以宣传),它用于兼容 vue2.7
和 vue3
以上的版本,下面我们来介绍一下它。
vue-draggable-plus
vue-draggable-plus
它用于延续 vue-draggable
核心理念,提供 vue
组件用于双向绑定数据列表,实现拖拽排序、克隆等功能,同时它还支持函数式、指令式的使用方式,让你使用起来更加方便,废话不多生活,我们先上图
更多演示请参考:demo
安装
npm install vue-draggable-plus
使用
vue-draggable-plus
支持三种使用方式:组件使用、函数式使用、指令式使用
下面我们来一一介绍:
- 组件式使用:
它和传统的vue组件的使用方式一样,支持双向绑定数据:
<template>
<VueDraggable
v-model="list"
:animation="150"
ghostClass="ghost"
@start="onStart"
@update="onUpdate"
>
<div
v-for="item in list"
:key="item.id"
>
{{ item.name }}
</div>
</VueDraggable>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type UseDraggableReturn, VueDraggable } from 'vue-draggable-plus'
const list = ref([
{
name: 'Joao',
id: 1
},
{
name: 'Jean',
id: 2
},
{
name: 'Johanna',
id: 3
},
{
name: 'Juan',
id: 4
}
])
</script>
<style scoped>
.ghost {
opacity: 0.5;
background: #c8ebfb;
}
</style>
- 函数式使用:
<template>
<div
ref="el"
>
<div
v-for="item in list"
:key="item.id"
>
{{ item.name }}
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useDraggable } from 'vue-draggable-plus'
const list = ref([
{
name: 'Joao',
id: 1
},
{
name: 'Jean',
id: 2
},
{
name: 'Johanna',
id: 3
},
{
name: 'Juan',
id: 4
}
])
const el = ref()
const { start } = useDraggable(el, list, {
animation: 150,
ghostClass: 'ghost',
onStart() {
console.log('start')
},
onUpdate() {
console.log('update')
}
})
</script>
<style scoped>
.ghost {
opacity: 0.5;
background: #c8ebfb;
}
</style>
它就像你使用 vueuse
一样接受一个 element
的引用,和一个响应式列表数据
- 指令式使用
由于指令的特殊性,指令只能绑定您在 setup
中绑定的数据,它并不能支持异步绑定数据,如果您的数据来自于异步获取,那么请您使用组件或者函数式实现
<template>
<ul
v-draggable="[
list,
{
animation: 150,
ghostClass: 'ghost',
onUpdate,
onStart
}
]"
>
<li
v-for="item in list"
:key="item.id"
>
{{ item.name }}
</li>
</ul>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { vDraggable } from 'vue-draggable-plus'
const list = ref([
{
name: 'Joao',
id: 1
},
{
name: 'Jean',
id: 2
},
{
name: 'Johanna',
id: 3
},
{
name: 'Juan',
id: 4
}
])
function onStart() {
console.log('start')
}
function onUpdate() {
console.log('update')
}
</script>
<style scoped>
.ghost {
opacity: 0.5;
background: #c8ebfb;
}
</style>
指定目标容器
在 Sortablejs
官方以往的 Vue
组件中,都是通过使用组件作为列表的直接子元素来实现拖拽列表,当我们使用一些组件库时,如果组件库中没有提供列表根元素的插槽,我们很难实现拖拽列表,vue-draggable-plus 完美解决了这个问题,它可以让你在任何元素上使用拖拽列表,我们可以使用指定元素的选择器,来获取到列表根元素,然后将列表根元素作为 Sortablejs
的 container
,我们来看一下用法:
- Table.vue
<template>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody class="el-table"> <-- 我们会将 .el-table 的选择器传递给 vue-draggable-plus -->
<tr v-for="item in list" :key="item.name" class="cursor-move">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</tbody>
</table>
</template>
<script setup lang="ts">
interface Props {
list: Record<'name' | 'id', string>[]
}
defineProps<Props>()
</script>
- App.vue
<template>
<section>
<div>
<-- 传递 .el-table 作为根元素,将 .el-table 的子元素作为拖拽项 -->
<VueDraggable v-model="list" animation="150" target=".el-table">
<Table :list="list"></Table>
</VueDraggable>
</div>
<div class="flex justify-between">
<preview-list :list="list" />
</div>
</section>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
import Table from './Table.vue'
const list = ref([
{
name: 'Joao',
id: '1'
},
{
name: 'Jean',
id: '2'
},
{
name: 'Johanna',
id: '3'
},
{
name: 'Juan',
id: '4'
}
])
</script>
来看效果:
结尾
如果您有使用需求,请参考文档:vue-draggable-plus,当然如果您不需要高度定制化,使用 vueuse 中的 useSortable 也是一样的。
如果它对您有用,请帮忙点个star:GitHub
来源:juejin.cn/post/7299353745506615347