Vue3拖拽组件

前言

HTML中拖拽可参考

https://www.psvmc.cn/article/2018-12-19-js-event.html

Vue3中有个方便拖拽的组件

vue-draggable-plus

https://vue-draggable-plus.pages.dev/guide/

安装

1
npm install vue-draggable-plus

示例

拖拽排序

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
<template>
<div class="flex">
<div ref="mImgList">
<div v-for="item in list" :key="item.id" class="item_div">
{{ item.name }}
</div>
</div>
<div>
{{ list }}
</div>
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useDraggable } from 'vue-draggable-plus'
const list = ref([
{
name: '项目1',
id: 1
},
{
name: '项目2',
id: 2
},
{
name: '项目3',
id: 3
}
])
const mImgList = ref()

useDraggable(mImgList, list, {
animation: 150,
ghostClass: 'ghost',
onStart() {
console.log('start')
},
onUpdate() {
console.log('update')
}
})
</script>

<style scoped>
.ghost {
opacity: 0.5;
background: #fa7e31 !important;
}

.item_div {
background: #fdfdfd;
border: 1px solid #eee;
width: 160px;
padding: 10px;
cursor: pointer;
}

.item_div + .item_div {
margin-top: 10px;
}
</style>

双列表拖拽

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<template>
<div class="outer_div">
<div ref="div1">
<div v-for="item in list1" :key="item.id" class="item_div">
{{ item.name }}
</div>
</div>
<div ref="div2">
<div v-for="item in list2" :key="item.id" class="item_div">
{{ item.name }}
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useDraggable } from 'vue-draggable-plus'
const list1 = ref([
{
name: '项目1',
id: 1
},
{
name: '项目2',
id: 2
},
{
name: '项目3',
id: 3
}
])
const div1 = ref()

useDraggable(div1, list1, {
group: 'group01',
animation: 150,
ghostClass: 'ghost',
onStart() {
console.log('start')
},
onUpdate() {
console.log('update')
}
})

const list2 = ref([
{
name: '项目4',
id: 4
}
])
const div2 = ref()

useDraggable(div2, list2, {
group: 'group01',
animation: 150,
ghostClass: 'ghost',
onStart() {
console.log('start')
},
onUpdate() {
console.log('update')
}
})
</script>

<style scoped>
.outer_div {
display: flex;
gap: 10px;
}
.ghost {
opacity: 0.5;
background: #fa7e31 !important;
}

.item_div {
background: #fdfdfd;
border: 1px solid #eee;
width: 160px;
padding: 10px;
cursor: pointer;
}

.item_div + .item_div {
margin-top: 10px;
}
</style>

拖拽克隆

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<template>
<div class="outer_div">
<div ref="div1">
<div v-for="item in list1" :key="item.id" class="item_div">
{{ item.name }}
</div>
</div>
<div>{{ list1 }}</div>
<div ref="div2">
<div v-for="item in list2" :key="item.id" class="item_div">
{{ item.name }}
</div>
</div>
</div>
</template>

<script setup>
import { ref } from 'vue'
import { useDraggable } from 'vue-draggable-plus'
import { v4 as uuidv4 } from 'uuid'

const list1 = ref([
{
name: '项目1',
id: '1'
},
{
name: '项目2',
id: '2'
},
{
name: '项目3',
id: '3'
}
])
const div1 = ref()

useDraggable(div1, list1, {
group: { name: 'group01', pull: false, put: true },
animation: 150,
ghostClass: 'ghost',
onSort() {

}
})

const list2 = ref([
{
name: '项目4',
id: '4'
},
{
name: '项目5',
id: '5'
}
])
const div2 = ref()

useDraggable(div2, list2, {
group: { name: 'group01', pull: 'clone', put: false },
sort: false,
animation: 150,
ghostClass: 'ghost',
clone(item) {
return {
name: item.name,
id: uuidv4()
}
}
})
</script>

<style scoped>
.outer_div {
display: flex;
gap: 10px;
}


.item_div {
background: #fdfdfd;
border: 1px solid #eee;
width: 160px;
padding: 10px;
cursor: pointer;
}

.ghost {
opacity: 0.5;
background: #fa7e31 !important;
}

.item_div + .item_div {
margin-top: 10px;
}
</style>

注意

onSort不是仅在排序的时候触发,添加、排序都会触发,但是删除不会触发。