Content Table

Vue 中实现拖拽

Sortable is a JavaScript library for reorderable drag-and-drop lists,下面介绍和 Vue 的简单集成:

  1. 添加依赖: yarn add sortablejs

  2. 页面中引入 Sortable: import Sortable from 'sortablejs'

  3. HTML 中创建被拖拽的列表

  4. 使用被拖拽元素的容器创建 Sortable 对象: Sortable.create(element, config)

  5. onEnd 事件触发时,修改 Vue 管理的数据

    和 Vue 集成最关键的是拖拽结束后需要手动修 Vue 管理的数据,Sortable 不会帮我们修改,具体请参考 onEnd 函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<template>
<div class="demo">
<!-- [3] HTML 中创建被拖拽的列表 -->
<ul id="items">
<li v-for="item in items" :key="item">{{ item }}</li>
</ul>
{{ items.join(', ') }}
</div>
</template>

<script>
// [2] 页面中引入 Sortable
import Sortable from 'sortablejs';

export default {
data() {
return {
items: [0, 1, 2, 3, 4, 5],
};
},
mounted() {
const e = document.querySelector('#items');

// [4] 使用被拖拽元素的容器创建 Sortable 对象
Sortable.create(e, {
animation: 150,
// [5] onEnd 事件触发时,修改 Vue 管理的数据
onEnd: (event) => {
// 拖放结束时, 界面上 HTML 的元素交换了顺序,但是 vue 的 this.items 中的数据没有被改变,需要手动修改:
// 1. 获取被拖拽的元素: oldIndex
// 2. 删除被拖拽的元素: oldIndex
// 3. 把被拖拽的元素插入新位置: newIndex
const item = this.items[event.oldIndex];
this.items.splice(event.oldIndex, 1);
this.items.splice(event.newIndex, 0, item);
}
});

// 给每一个 li 增加背景,方便拖拽时观察
const COLORS = ['red', 'green', 'blue', 'yellow', 'pink', 'violet'];
document.querySelectorAll('li').forEach((li, i) => {
li.className = COLORS[i++];
});
},
};
</script>

<style lang="scss">
.demo {
ul#items {
list-style: none;

li {
margin-bottom: 10px;
width: 100px;
text-align: center;
font-weight: bold;
}
}

.red { background: red; }
.green { background: green; }
.blue { background: blue; }
.yellow { background: yellow; }
.pink { background: pink; }
.violet { background: violet; }
}
</style>

Vue.Draggable is Vue drag-and-drop component based on Sortable.js,也可以直接使用这个组件 ,这样就不需要自己修改 Vue 管理的数据了。