vue3使用vue-draggable会有如下bug
微信截图_20220307110305.png
bace7f2a18d74201980a7fe9368ad135.png
vue3要安装vue-draggable-next
npm install vue-draggable-next --save
代码
<template>
<div>
<div class="left-board">
<el-scrollbar class="left-scrollbar">
<div class="components-list">
<div v-for="(item, listIndex) in comList" :key="listIndex">
<div class="components-title">
<svg-icon icon-class="component" />
{{ item.title }}
</div>
<draggable
class="components-draggable"
draggable=".components-item"
:sort="false"
:list="item.list"
:clone="cloneComponent"
:group="{ name: 'componentsGroup', pull: 'clone', put: false }"
@end="onEnd"
>
<div class="components-item" v-for="(element, index) in item.list" :key="index">
<div class="components-body">
<i class="el-icon-edit"></i>
{{ element.label }}
</div>
</div>
</draggable>
</div>
</div>
</el-scrollbar>
</div>
<div class="center-board">
<el-scrollbar>
<el-form
label-width="120px"
>
<div class="center-scrollbar">
<draggable class="drawing-board" :list="drawingList.list" :animation="340" group="componentsGroup">
<div v-for="(item,index) in drawingList.list" :key="index" class="drawing-item">
<el-form-item :label="item.label">
<template v-if="item.tagIcon == 'input'">
<el-input></el-input>
</template>
<template v-if="item.tagIcon == 'textarea'">
<el-input type="textarea"></el-input>
</template>
<template v-if="item.tagIcon == 'password'">
<el-input type="password"></el-input>
</template>
<template v-if="item.tagIcon == 'switch'">
<el-switch />
</template>
</el-form-item>
<el-icon @click="delHandler(index)" class="drawing-item-delete"><delete /></el-icon>
</div>
</draggable>
</div>
</el-form>
</el-scrollbar>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue';
import { VueDraggableNext } from 'vue-draggable-next';
import { Delete } from '@element-plus/icons-vue';
export default defineComponent({
components: {
draggable: VueDraggableNext,
delete: Delete,
},
setup() {
let tempActiveData:any;
const comList:any = [
{
title: '输入型组件',
list: [
{
label: '单行文本',
tagIcon: 'input',
},
{
label: '多行文本',
tagIcon: 'textarea',
},
{
label: '密码',
tagIcon: 'password',
},
],
},
{
title: '选择型组件',
list: [],
},
{
title: '布局型组件',
list: [],
},
];
const drawingList: any = reactive({
list: [
{
label: '单行文本',
tagIcon: 'input',
},
{
label: '多行文本',
tagIcon: 'textarea',
},
{
label: '密码',
tagIcon: 'password',
},
{
label: '开关',
tagIcon: 'switch',
}
]
});
// 拖动结束
const onEnd = (obj: any) => {
if (obj.from != obj.to) {
drawingList.list.splice(obj.newIndex, 0,tempActiveData);
}
};
// 获取当前拖动的对象
const cloneComponent = (item:any) => {
tempActiveData = item;
};
// 删除元素
const delHandler = (index: number) => {
drawingList.list.splice(index,1);
};
return {
comList,
drawingList,
onEnd,
cloneComponent,
delHandler,
};
},
})
</script>
<style lang="less" scoped>
.left-board {
width: 260px;
position: absolute;
left: 0;
top: 0;
height: 100vh;
.components-title {
font-size: 14px;
color: #222;
margin: 6px 2px;
}
.components-item {
display: inline-block;
width: 48%;
margin: 1%;
// 限制拖动过去又来回的动画
transition: transform 0ms !important;
.components-body {
padding: 8px 10px;
background: #f6f7ff;
font-size: 12px;
cursor: move;
border: 1px dashed #f6f7ff;
border-radius: 3px;
}
}
}
.center-board {
height: 100vh;
width: auto;
margin: 0 350px 0 260px;
border-left: 1px solid #f1e8e8;
border-right: 1px solid #f1e8e8;
.center-scrollbar {
padding: 12px 12px 15px 12px;
}
.drawing-item {
padding: 10px 7.5px;
position: relative;
cursor: move;
margin-bottom: 15px;
&.active{
background: #f6f7ff;
}
}
.drawing-item-delete {
right: 24px;
border-color: #F56C6C;
color: #F56C6C;
background: #fff;
position: absolute;
top: -10px;
width: 22px;
height: 22px;
line-height: 22px;
text-align: center;
border-radius: 50%;
font-size: 12px;
border: 1px solid;
cursor: pointer;
z-index: 1;
}
.drawing-board{
height: 100%;
position: relative;
.sortable-ghost {
position: relative;
display: block;
overflow: hidden;
// 当前列表切换排序的样式
&::before {
content: " ";
position: absolute;
left: 0;
right: 0;
top: 0;
height: 3px;
background: rgb(89, 89, 223);
z-index: 2;
}
}
// 左边拖拽过来的样式
.components-item.sortable-ghost {
width: 100%;
height: 60px;
background-color: #f6f7ff;
color: red;
}
}
}
</style>
网友评论