介绍
在Web端做组件拖拽功能在当下的各类项目中不足为奇,因为我们拥有非常不错的第三方组件供我们使用,让我们实现这样的功能变得非常简单轻松,今天就介绍一个在Vue3中使用的一个拖拽排序组件——vue.draggable.next,它是SortableJS官方基于SortableJS针对Vue3开发的一个拖拽排序组件!从它Github的主页来看,官方实现了在各个框架(包括原生js)的JavaScript库,相信很多小伙伴或多或少都用过!
特点
- 完全支持Sortable.js特性
包括触摸设备、拖动手柄和可选文本、智能自动滚动、支持不同列表间的拖放、不依赖 jQuery
- 保持 HTML 响应式数据列表的同步
- 兼容 Vue.js 3.0 过渡组
- 取消已经可拖拽的组件
- 完全控制任何更改的事件
- 重用现有的 UI 库组件(vuetify, element, 以及vue material等等)并使用 tag 和 componentData 道具使它们可拖动
安装使用
下面我们直接安装体验一番,这里我们可以使用npm或者yarn进行安装,笔者相较于习惯yarn
yarn add vuedraggable@next
npm i -S vuedraggable@next
下面是笔者录制的一个Gif图:
//代码示例
<template>
<div class="wrap">
<draggable
v-model="list"
@start="drag = true"
@end="drag = false"
item-key="id"
>
<template #item="{ element }">
<div class="drag">{{ element.name }}</div>
</template>
</draggable>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import draggable from "vuedraggable";
export default defineComponent({
name: "VueDrag",
components: {
draggable,
},
setup() {
const drag = ref(false);
const list = ref([
{
name: "茅檐长扫净无苔",
id: 0,
},
{
name: "花木成畦手自栽",
id: 1,
},
{
name: "一水护田将绿绕",
id: 2,
},
{
name: "两山排闼送青来",
id: 3,
},
]);
return { drag, list };
},
});
</script>
<style scoped>
.wrap {
margin-top: 500px;
margin-left: 900px;
width: 800px;
text-align: center;
border: 1px rebeccapurple solid;
padding: 20px;
}
.drag {
background-color: cadetblue;
color: aliceblue;
font-size: 28px;
height: 48px;
line-height: 48px;
border: 1px royalblue solid;
border-radius: 6px;
margin: 10px;
}
</style>
我们可以看到是以slot插槽(slot-props)的方式实现的。
- 在两个不同的拖拽组件间相互拖拽
group属性设为一致
<div class="l1">
<h3>列表1</h3>
<draggable class="list-group" :list="list1" group="tangsh" itemKey="name">
<template #item="{ element, index }">
<div>{{ element.name }}</div>
</template>
</draggable>
</div>
<div class="l2">
<h3>列表2</h3>
<draggable class="list-group" :list="list2" group="tangsh" itemKey="name">
<template #item="{ element, index }">
<div>{{ element.name }}</div>
</template>
</draggable>
</div>
- 动画效果演示
<template>
<div class="row">
<div class="col-6">
<h3>动画效果</h3>
<draggable
class="list-group"
tag="transition-group"
:component-data="{
tag: 'ul',
type: 'transition-group',
name: !drag ? 'flip-list' : null,
}"
v-model="list"
v-bind="dragOptions"
@start="drag = true"
@end="drag = false"
item-key="order"
>
<template #item="{ element }">
<div class="list-group-item">
<i
:class="
element.fixed ? 'fa fa-anchor' : 'glyphicon glyphicon-pushpin'
"
@click="element.fixed = !element.fixed"
aria-hidden="true"
></i>
{{ element.name }}
</div>
</template>
</draggable>
</div>
</div>
</template>
<script>
import draggable from "vuedraggable";
const message = ["春眠不觉晓,", "处处闻啼鸟。", "夜来风雨声,", "花落知多少。"];
export default {
display: "Transitions",
order: 7,
components: {
draggable,
},
data() {
return {
list: message.map((name, index) => {
return { name, order: index + 1 };
}),
drag: false,
};
},
methods: {
sort() {
this.list = this.list.sort((a, b) => a.order - b.order);
},
},
computed: {
dragOptions() {
return {
animation: 200,
group: "description",
disabled: false,
ghostClass: "ghost",
};
},
},
};
</script>
<style>
.flip-list-move {
transition: transform 0.5s;
}
.no-move {
transition: transform 0s;
}
.ghost {
opacity: 0.5;
background: #c8ebfb;
}
.list-group {
margin-left: 800px;
margin-top: 300px;
min-height: 20px;
}
.list-group-item {
cursor: move;
background-color: cadetblue;
height: 48px;
width: 600px;
margin-top: 10px;
line-height: 48px;
color: #c8ebfb;
font-size: 24px;
}
.list-group-item i {
cursor: pointer;
}
</style>
总结
本文只是简单介绍几个例子,官方中还介绍了其它一些更加复杂的操作,包括在表格行和列的拖拽等等操作,使用它都不是难事,官网针对每一个例子都有完整的代码演示,使用起来相当的简单,如果你有类似的需求,则可以尝试使用它来实现你想要的效果,希望对你有所帮助!