环境:Vue3+setup语法
中文文档:vue.draggable.next group 分组拖拽 - itxst.com
1. 下载依赖
yarn add vuedraggable@next
npm i -S vuedraggable@next
2. 属性
属性名称 | 说明 |
---|---|
group | 如果一个页面有多个拖拽区域,通过设置group名称可以实现多个区域之间相互拖拽 或者 { name: "...", pull: [true, false, 'clone', array , function], put: [true, false, array , function] } |
sort | 是否开启排序,如果设置为false,它所在组无法排序 |
delay | 鼠标按下多少秒之后可以拖拽元素 |
touchStartThreshold | 鼠标按下移动多少px才能拖动元素 |
disabled | :disabled= "true",是否启用拖拽组件 |
animation | 拖动时的动画效果,如设置animation=1000表示1秒过渡动画效果 |
handle | :handle=".mover" 只有当鼠标在class为mover类的元素上才能触发拖到事件 |
filter | :filter=".unmover" 设置了unmover样式的元素不允许拖动 |
draggable | :draggable=".item" 样式类为item的元素才能被拖动 |
ghost-class | :ghost-class="ghostClass" 设置拖动元素的占位符类名,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true |
chosen-class | :ghost-class="hostClass" 被选中目标的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true |
drag-class | :drag-class="dragClass"拖动元素的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true |
force-fallback | 默认false,忽略HTML5的拖拽行为,因为h5里有个属性也是可以拖动,你要自定义ghostClass chosenClass dragClass样式时,建议forceFallback设置为true |
fallback-class | 默认false,克隆选中元素的样式到跟随鼠标的样式 |
fallback-on-body | 默认false,克隆的元素添加到文档的body中 |
fallback-tolerance | 按下鼠标移动多少个像素才能拖动元素,:fallback-tolerance="8" |
scroll | 默认true,有滚动区域是否允许拖拽 |
scroll-fn | 滚动回调函数 |
scroll-fensitivity | 距离滚动区域多远时,滚动滚动条 |
scroll-speed | 滚动速度 |
3. 确认自己的需求,我这里以分组拖拽为例
<template>
<div class="msg">{
{ state.message }}</div>
<div class="itxst">
<div class="group">
<draggable :list="state.modules.arr1" ghost-class="ghost" handle=".move" filter=".forbid" :force-fallback="true"
chosen-class="chosenClass" animation="300" @start="onStart" @end="onEnd" :group="state.groupA"
:fallback-class="true" :fallback-on-body="true" :touch-start-threshold="50" :fallback-tolerance="50"
:move="onMove" :sort="false">
<template #item="{ element }">
<div class="item move">
<label class="move">{
{ element.name }}</label>
<span v-html="element.name == '消息' ? 'www.itxst.com' : '内容....'"></span>
</div>
</template>
</draggable>
</div>
<div class="group">
<draggable class="Bzu" :list="state.modules.arr2" ghost-class="ghost" handle=".move" filter=".forbid"
:force-fallback="true" chosen-class="chosenClass" animation="300" @start="onStart" @end="onEnd"
group="itxst" :fallback-class="true" :fallback-on-body="true" :touch-start-threshold="50"
:fallback-tolerance="50" :move="onMove">
<template #item="{ element }">
<div class="item move">
<label class="move">{
{ element.name }}</label>
<span>内容....</span>
</div>
</template>
</draggable>
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
//导入draggable组件
import draggable from "vuedraggable";
const state = reactive({
message: "拖拽",
groupA: {
name: "itxst",
put: false, //允许拖入
pull: "clone"
},
modules: {
arr1: [
{ name: "A组", id: 1 },
{ name: "库存", id: 2 },
{ name: "销量", id: 3 },
{ name: "日志", id: 4 },
{ name: "员工", id: 6 },
{ name: "报表", id: 7 },
],
arr2: [
{ name: "B组", id: 5 },
],
},
});
//拖拽开始的事件
const onStart = () => {
console.log("开始拖拽");
};
//拖拽结束的事件
const onEnd = () => {
console.log("结束拖拽");
};
const onMove = (e) => {
//不允许停靠
if (e.relatedContext.element.disabledPark == true) return false;
return true;
};
</script>
<style >
body {
padding: 0px;
margin: 0px;
background-color: #f1f1f1;
}
.msg {
padding: 10px 20px 0px 20px;
}
.itxst {
background-color: #f1f1f1;
display: flex;
padding: 20px;
}
.group {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-content: center;
width: 32%;
margin-right: 20px;
border: 1px solid red;
height: 600px;
}
.item {
border: solid 1px #ddd;
padding: 0px;
text-align: left;
background-color: #fff;
margin-bottom: 10px;
display: flex;
height: 36px;
user-select: none;
}
.item>label {
padding: 6px 10px;
color: #333;
}
.item>label:hover {
cursor: move;
}
.item>span {
padding: 6px 10px;
color: #666;
}
.ghost {
border: solid 1px rgb(19, 41, 239) !important;
}
.chosenClass {
opacity: 1;
border: solid 1px red;
}
.fallbackClass {
background-color: aquamarine;
}
.Bzu {
height: 100%;
}
</style>