Vue Draggable 入门 网页列表拖动实现排序
2024-05-17
阅读 {{counts.readCount}}
评论 {{counts.commentCount}}
## 前言
最近打算给 [极简导航](https://nav.zzzmh.cn) 的配置收藏页面加一个拖动功能,很久之前用过一次Vue Draggable,最近搞忘了,再复习一下,顺便写个笔记
基于 `VUE2` `Sortablejs` `Vue.Draggable`
<br><br>
## 折腾
直接上代码
一个最简单的demo
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<title>vue.draggable例子 1</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/sortablejs@1.8.4/Sortable.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.20.0/vuedraggable.umd.min.js"></script>
<style scoped>
body {
user-select: none;
}
.item {
height: 50px;
width: 500px;
border: #acacac solid 1px;
border-radius: 10px;
display: flex;
align-items: center;
padding: 16px;
margin: 10px 0;
}
.item i {
cursor: move;
width: 50px;
height: 20px;
}
.item i:hover {
cursor: move;
}
</style>
</head>
<body style="padding:10px;">
<div id="app">
<p>
一个基于官网例子的例子,使用Vue2 + VueDraggable,目前实现的是长按整个卡片都会拖动成功
</p>
<div>{{drag ? '拖拽中' : '拖拽停止'}}</div>
<draggable v-model="myArray" chosen-class="chosen" force-fallback="true" group="people" animation="200"
:disabled="false">
<transition-group>
<div class="item" v-for="element in myArray" :key="element.id">
<i>标签</i>
<span>{{element.name}}</span>
</div>
</transition-group>
</draggable>
</div>
<script>
Vue.component('vuedraggable', window.vuedraggable)
const app = new Vue({
el: '#app',
components: {
vuedraggable: window.vuedraggable,//当前页面注册组件
},
data() {
return {
drag: false,
myArray: [
{id: 1, name: '我是第一条测试例子abcdefg!@#$'},
{id: 2, name: '我是第二条测试例子abcdefg!@#$'},
{id: 3, name: '我是第三条测试例子abcdefg!@#$'},
{id: 4, name: '我是第四条测试例子abcdefg!@#$'},
{id: 5, name: '我是第五条测试例子abcdefg!@#$'},
]
};
},
methods: {
}
});
</script>
</body>
</html>
```
效果演示
![](/api/file/getImage?fileId=664700e1da7405001404cd5b)
这里有个小问题,在正式项目中,整个卡片长按拖动,可能会误操作。目标是希望实现,用户长按指定标签实现拖动,并且可以在多组数据之间来回拖动。
这里我参考了一下官方例子
https://sortablejs.github.io/Vue.Draggable/#/handle
https://github.com/SortableJS/Vue.Draggable/blob/master/example/components/handle.vue
修改后的代码如下
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<title>vue.draggable例子 1</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/sortablejs@1.8.4/Sortable.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.20.0/vuedraggable.umd.min.js"></script>
<style scoped>
body {
user-select: none;
}
.item {
height: 50px;
width: 500px;
border: #acacac solid 1px;
border-radius: 10px;
display: flex;
align-items: center;
padding: 16px;
margin: 10px 0;
}
.item i {
cursor: move;
width: 50px;
height: 20px;
}
.item i:hover {
cursor: move;
}
.draggable{
border: #ff6600 dashed 1px;
width: 100%;
margin-bottom: 10px;
}
</style>
</head>
<body style="padding:10px;">
<div id="app">
<p>
一个基于官网例子的例子,使用Vue2 + VueDraggable,目前实现的是长按整个卡片都会拖动成功
</p>
<div>{{drag ? '拖拽中' : '拖拽停止'}}</div>
<draggable class="draggable" v-model="myArray1" chosen-class="chosen" force-fallback="true" group="people" animation="200"
handle=".handle">
<transition-group>
<div class="item" v-for="element in myArray1" :key="element.id">
<i class="handle">标签</i>
<span>{{element.name}}</span>
</div>
</transition-group>
</draggable>
<draggable class="draggable" v-model="myArray2" chosen-class="chosen" force-fallback="true" group="people" animation="200"
handle=".handle">
<transition-group>
<div class="item" v-for="element in myArray2" :key="element.id">
<i class="handle">标签</i>
<span>{{element.name}}</span>
</div>
</transition-group>
</draggable>
</div>
<script>
Vue.component('vuedraggable', window.vuedraggable)
const app = new Vue({
el: '#app',
components: {
vuedraggable: window.vuedraggable,//当前页面注册组件
},
data() {
return {
drag: false,
myArray1: [
{id: 1, name: '我是第一条测试例子abcdefg!@#$'},
{id: 2, name: '我是第二条测试例子abcdefg!@#$'},
{id: 3, name: '我是第三条测试例子abcdefg!@#$'},
{id: 4, name: '我是第四条测试例子abcdefg!@#$'},
{id: 5, name: '我是第五条测试例子abcdefg!@#$'},
],
myArray2: [
{id: 6, name: '我是第六条测试例子abcdefg!@#$'},
{id: 7, name: '我是第七条测试例子abcdefg!@#$'},
{id: 8, name: '我是第八条测试例子abcdefg!@#$'},
{id: 9, name: '我是第九条测试例子abcdefg!@#$'},
]
};
},
methods: {
}
});
</script>
</body>
</html>
```
效果演示
![](/api/file/getImage?fileId=66470181da7405001404cd66)
<br><br>
## END
由于GiteePage停止提供服务,无法给出线上测试地址,建议直接用官方例子测试
[https://sortablejs.github.io/Vue.Draggable/#/handle](https://sortablejs.github.io/Vue.Draggable/#/handle)
本例子源码
[https://gitee.com/zzzmhcn/vue-draggable-demo](https://gitee.com/zzzmhcn/vue-draggable-demo)