vue3+Ant Design Vue Transfer 穿梭框实现拖拽式列表
实现拖拽式列表必备!!!!!最近在写公司项目时需要在Ant Design Vue穿梭框右侧实现拖拽列表排序功能,而Ant Design Vue本身无此功能,所以自己写了一个,实现代码及原理如下://使用到VUE中的:@dragstart 拖拽开始时在被拖拽元素上触发此事件@drop.prevent 被拖拽的元素在目标元素上同时鼠标放开触发的事件,此事件作用在目标元素上@dragover.preve
·
求点赞关注!!!!!!!!!!!!!
最近在写公司项目时需要在Ant Design Vue穿梭框右侧实现拖拽列表排序功能,而Ant Design Vue本身无此功能,所以自己写了一个,实现代码及原理如下:
//使用到VUE中的:
@dragstart 拖拽开始时在被拖拽元素上触发此事件
@drop.prevent 被拖拽的元素在目标元素上同时鼠标放开触发的事件,此事件作用在目标元素上
@dragover.prevent 拖拽元素在目标元素上移动的时候触发的事件,此事件作用在目标元素上
1.Transfer 穿梭框HTML代码
<a-transfer :style="{width: '400px'}" :data-source="mockData"
:titles="['列表', '已选列表']" :disabled="disabled"
:target-keys="formState.targetKeys" :selected-keys="transfer.selectedKeys"
:render="item => item.title" @change="handleChange" @selectChange="handleSelectChange">
<template #children="{direction,filteredItems,onItemSelect}">
<div class="transfer">
<div v-if="direction==='right'" class="transfer-right">
<div draggable="true" v-for="(item,index) in filteredItems" :key="item.key"
@mouseenter="isTarget(true,item)"
@mouseleave="isTarget(false,item)"
@dragstart="handleDragstart(index)"
@drop.prevent="handleDrop()"
@dragover.prevent="handleDragover(index)"
@click="()=>checkChange(item.checked,item.key,onItemSelect)"
class="transfer-right-item"
>
<a-checkbox
:checkedKeys="[...formState.targetKeys, ...transfer.selectedKeys]"
v-model:checked="item.checked"
></a-checkbox>
<div class="transfer-right-item-content">
<span> {{item.title}}</span>
<MenuOutlined v-show="item.showMenu" />
</div>
</div>
</div>
<div v-if="direction==='left'" class="transfer-left">
<div v-for="item in filteredItems" :key="item.key" class="transfer-left-item"
@click="()=>checkChange(item.checked,item.key,onItemSelect)">
<a-checkbox
:checkedKeys="[...formState.targetKeys, ...transfer.selectedKeys]"
v-model:checked="item.checked"
></a-checkbox>
{{item.title}}
</div>
</div>
</div>
</template>
</a-transfer>
2.Transfer 穿梭框JavaScript代码
setup()中的代码,下面的所用到的函数代码
// 选项在两栏之间转移时的回调函数
const handleChange = (nextTargetKeys, direction, moveKeys) => {
moveKeys.forEach((item) => {
drawerData.mockData.forEach((items, index) => {
if (item === items.key)drawerData.mockData[index].checked = false;
});
});
if (direction === 'right') {
formState.targetKeys.push(...moveKeys);
} else formState.targetKeys = nextTargetKeys;
};
// 选中项发生改变时的回调函数
const handleSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
// 判断右边列表是否全选 是的话右边多选框全为true
if (targetSelectedKeys.length === formState.targetKeys.length) {
targetSelectedKeys.forEach((item) => {
drawerData.mockData.forEach((items, index) => {
if (item === items.key)drawerData.mockData[index].checked = true;
});
});
}
// 判断左边列表是否全选 是的话左边多选框全为true
if (sourceSelectedKeys.length === drawerData.mockData.length - formState.targetKeys.length) {
sourceSelectedKeys.forEach((item) => {
drawerData.mockData.forEach((items, index) => {
if (item === items.key)drawerData.mockData[index].checked = true;
});
});
}
drawerData.transfer.selectedKeys = [...sourceSelectedKeys, ...targetSelectedKeys];
};
const handleDrop = () => {
// 删除老的
const changeItem = formState.targetKeys.splice(drawerData.oldItemIndex, 1)[0];
// 在列表中目标位置增加新的
formState.targetKeys.splice(drawerData.newItemIndex, 0, changeItem);
};
const handleDragstart = (index) => { drawerData.oldItemIndex = index; };
const handleDragover = (index) => { drawerData.newItemIndex = index; };
// 用于判断选中了哪些多选框
const checkChange = (checked, key, onItemSelect) => {
drawerData.mockData.forEach((items, index) => {
if (key === items.key)drawerData.mockData[index].checked = !checked;
});
onItemSelect(key, !checked);
};
// 穿梭框列表图标显示与隐藏
const isTarget = (falg, e) => {
let key = false;
formState.targetKeys.forEach((item) => { if (e.key === item)key = item; });
if (key !== false) {
drawerData.mockData.forEach((item, index) => {
if (e.key === item.key)drawerData.mockData[index].showMenu = falg;
});
}
};
3.Transfer 穿梭框样式代码
我使用的是less,大家可以根据自己的需求进行更改
:deep(.ant-transfer-list-body){
width: 100px;
height: 200px;
}
:deep(.ant-transfer-list-body-customize-wrapper){
padding: 0 12px 0 0px;
height: 100%;
}
.transfer{
width: 178px;
height: 200px;
overflow: hidden;
}
.transfer-left,.transfer-right{
width:100%;
height: 200px;
overflow-y: auto;
&-item{
padding-left: 12px;
width: 100%;
height: 30px;
display: flex;
align-items: center;
&-content{
width: 100%;
display: flex;
padding: 10px;
align-items: center;
justify-content: space-between;
}
}
&-item:hover{
background: #ccc;
}
}
更多推荐
已为社区贡献6条内容
所有评论(0)