一、基本使用(列表拖拽和表格拖拽)
1、效果
2、下载插件
npm i vuedraggable // 2.24.3
3、使用
<template>
<div class="draggable">
<button @click="disabled = !disabled">{{disabled?'启用拖拽':'禁用拖拽'}}</button>
<h1>列表拖拽</h1>
<div>{{drag?'拖拽中':'拖拽停止'}}</div>
<Draggable tag='ul' v-model="list" :disabled="disabled" animation="300" @start="handleStart" @end="handleEnd" chosen-class="chosen">
<li v-for="(item,index) of list" :key="index">{{item}}</li>
</Draggable>
<h1>表格拖拽</h1>
<div>{{drag?'拖拽中':'拖拽停止'}}</div>
<Draggable tag='table' v-model="list" :disabled="disabled" animation="300" @start="handleStart" @end="handleEnd">
<tr v-for="(item,index) of list" :key="index">
<td>{{index}}</td>
<td>{{item}}</td>
</tr>
</Draggable>
</div>
</template>
<script>
import Draggable from 'vuedraggable'
export default {
data() {
return {
disabled: false,
drag: false,
list: ['张三', '李四', '王五', '赵六']
}
},
methods: {
//开始拖拽事件
handleStart() {
this.drag = true
},
//拖拽结束事件
handleEnd() {
this.drag = false
console.log('handleEnd', this.list)
}
},
components: { Draggable }
}
</script>
<style lang='less' scoped>
.draggable {
padding: 10px;
> ul {
li {
background-color: greenyellow;
user-select: none;
line-height: 30px;
&:hover {
background-color: yellowgreen;
cursor: move;
}
+ li {
margin-top: 10px;
}
&.chosen {
border: solid 2px skyblue;
}
}
}
> table {
border-collapse: collapse;
tr {
td {
width: 100px;
line-height: 30px;
background-color: greenyellow;
border: 1px solid #ccc;
}
}
}
}
</style>
二、多列拖拽
1、效果
2、代码
<template>
<div class="draggable">
<h1>多列拖拽</h1>
<div>{{warning}}</div>
<div class="line-wrapper">
<Draggable tag='ul' v-model="list" :group="groupA" animation="300">
<li v-for="(item,index) of list" :key="index">{{item}}</li>
</Draggable>
<Draggable tag='ul' v-model="list1" :group="groupB" animation="300">
<li v-for="(item,index) of list1" :key="index">{{item}}</li>
</Draggable>
</div>
</div>
</template>
<script>
import Draggable from 'vuedraggable'
export default {
data() {
return {
drag: false,
list: ['张三', '李四', '王五', '赵六'],
list1: ['罗翔'],
groupA: {
name: 'site',
pull: true, // 是否允许拖出当前组,默认为true
put: true // 是否允许拖入当前组,默认为true
},
groupB: { name: 'site', pull: () => this.list1.length > 2 }
}
},
computed: {
warning(vm) {
return vm.list1.length <= 2 ? '不能再拖出了' : ''
}
},
components: { Draggable }
}
</script>
<style lang='less' scoped>
.draggable {
padding: 10px;
.line-wrapper {
display: flex;
> ul {
flex: 0.5;
border: 2px solid pink;
li {
background-color: greenyellow;
user-select: none;
line-height: 30px;
&:hover {
background-color: yellowgreen;
cursor: move;
}
+ li {
margin-top: 10px;
}
&.chosen {
border: solid 2px skyblue;
}
}
}
}
}
</style>
3、实现多列拖拽的属性
当两个
Draggable组件传入group属性时,值为同一个,例如group='site',那么这两个组件可以实现相互之间的拖拽或者传入
:group='groupA',:group='groupB',设置name值为同一个,也可以实现相互之前的拖拽。对象形式传入时,pull和put默认都是true,可以设置为布尔值或者一个函数
三、其他属性
1、delay="100"
鼠标按下后100ms后才能拖拽,防止误操作。默认为0
2、animation="300"
设置动画时间。默认为0
3、handle=".mover"
指定可以进行拖拽的元素类名。默认为空,mover为自定义的类名
<Draggable tag='ul' v-model="list" animation="300" handle=".mover">
<li v-for="(item,index) of list" :key="index">
<el-button class="mover">+</el-button>
{{item}}
</li>
</Draggable>
el-button标签为可拖拽元素
4、filter=".forbid"
指定不可以被拖拽的元素类名。默认为空,forbid为自定义的类名
<Draggable tag='ul' v-model="list" animation="300" handle=".mover" filter=".forbid">
<li v-for="(item,index) of list" :key="index">
<el-button class="mover" :class="{forbid:index===0}">+</el-button>
{{item}}
</li>
</Draggable>
index为0的元素不能被拖拽
5、:move="handleMove"
当拖拽时,获取到当前事件对象:
从中可以拿到目标对象,可以做出判断,禁止拖拽到此目标
与filter=".forbid"结合便可以达到禁止此项拖拽,并且禁止别的项拖拽到此项的位置上。注意:需要被禁止的项一般要放到列表的最前面或最后面
<Draggable tag='ul' v-model="list" :group="groupA" animation="300" filter=".forbid" :move='handleMove'>
<li :class="{forbid:item==='王五'}" v-for="(item,index) of list" :key="index">{{item}}</li>
</Draggable>
handleMove(e) {
console.log(e, e.relatedContext.element)
return e.relatedContext.element !== '王五'
}
6、chosen-class ghost-class 自定义鼠标按下和拖拽时的类名
默认的类名为sortable-chosen(鼠标按下)、sortable-ghost(鼠标拖拽)
可以通过chosen-class ghost-class自定义
7、拷贝拖拽
通过pull: 'clone'实现拷贝拖拽
<Draggable tag='ul' v-model="list" :group='groupA' animation="300" :move="handleMove">
<li v-for="item of list" :key="item.id">{{item.name}}</li>
</Draggable>
<Draggable tag='ul' v-model="arr2" group="site" animation="300">
<li v-for="item of arr2" :key="item.id">{{item.name}}</li>
</Draggable>
data() {
return {
list: [
{ id: 1, name: 'www.itxst.com' },
{ id: 2, name: 'www.jd.com' },
{ id: 3, name: 'www.baidu.com' },
{ id: 4, name: 'www.taobao.com' },
{ id: 5, name: 'www.google.com' }
],
arr2: [{ id: 11, name: '常用菜单' }],
groupA: { name: 'site', pull: 'clone' }
}
},
methods: {
handleMove(e) {
const draggedId = e.draggedContext.element.id
if (this.arr2.map((item) => item.id).includes(draggedId)) return false
}
}