- 适用组件:
导入,注册组件,然后使用
<DragTransfer :checkedSearchList="checkedSearchList" leftTitle="未展示筛选项" rightTitle="常用筛选区" :data="checkedSearchLists" :props="transferProps" @chageRightData="updateSelectedItems" ></DragTransfer>
参数解释:
:checkedSearchList="checkedSearchList" 右边已选择的数据 :data="data" 所有数据,左边和右边一起的数据 leftTitle="未选择字段" 左边标题 rightTitle="已选择字段" 右边标题 :props="transferProps" 字段映射 @chageRightData="updateSelectedItems" 接受子组件传递的值
vue data中定义:
transferProps: { value: "rfidSetId", label: "rfidSetName", },
-
左右拖拽加复选组件:
src/components/DragTransfer.vue
<template>
<div class="drag-transfer">
<div class="drag-transfer-content">
<div class="drag-transfer-left">
<span class="tipSapn1"></span>
<div class="drag-transfer-title">
{{ leftTitle }}
<span class="dragSpan">可拖拽字段进行配置</span>
</div>
<div
id="left"
class="drag-transfer-item"
@drop="drop"
@dragover="allowDrop"
>
<template v-for="(item, index) in leftData">
<div
:key="index"
draggable="true"
@dragstart="dragstart"
:id="item.key"
@click="checkLeftElement(item)"
:class="[
'drag-transfer-item-name',
item.checked ? 'dragActive' : '',
]"
>
<input
class="checkInput"
type="checkbox"
v-model="item.checked"
@change="checkboxLeftChanged(item)"
/>
<span class="checkSpan">{{ item.label }}</span>
</div>
</template>
</div>
</div>
<div class="drag-transfer-center">
<div class="twoImage">
<img
src="@/assets/img/toLeft.png"
alt=""
v-if="checkRight.length === 0"
/>
<img
src="@/assets/img/toLeftBG.png"
alt=""
v-if="checkRight.length !== 0"
@click="turnLeft"
/>
<img
src="@/assets/img/toRight.png"
alt=""
v-if="checkLeft.length === 0"
/>
<img
src="@/assets/img/toRightBG.png"
alt=""
v-if="checkLeft.length !== 0"
@click="turnRight"
/>
</div>
</div>
<div class="drag-transfer-right">
<span class="tipSapn1"></span>
<div class="drag-transfer-title">{{ rightTitle }}</div>
<div
id="right"
class="drag-transfer-item"
@drop="drop"
@dragover="allowDrop"
>
<template v-for="(item, index) in rightData">
<div
:key="index"
draggable="true"
@dragstart="dragstart"
:id="item.key"
:class="[
'drag-transfer-item-name',
item.checked ? 'dragActive' : '',
]"
>
<input
class="checkInput"
type="checkbox"
v-model="item.checked"
@change="checkboxRightChanged(item)"
/>
<span class="checkSpan">{{ item.label }}</span>
</div>
</template>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "drag-transfer",
model: {
prop: "rightData",
event: "chageRightData",
},
props: {
rightData: {
type: Array,
default: () => [],
},
checkedSearchList: {
type: Array,
default: () => [],
},
leftTitle: {
type: String,
default: "未选择",
},
rightTitle: {
type: String,
default: "已选择",
},
props: {
type: Object,
default: () => ({
value: "value",
label: "label",
}),
},
data: {
type: Array,
default: () => [],
},
},
data() {
return {
leftData: [],
rightData: [],
tableData: [],
leftKey: "",
checkLeft: [],
checkRight: [],
};
},
mounted() {
this.rightData = this.checkedSearchList;
},
watch: {
data: {
handler(val) {
const self = this;
this.leftData = [];
this.data.forEach(function (element) {
const index = self.rightData.findIndex(
(x) => x["key"] == element["key"]
);
if (index == -1) {
self.leftData.push(element);
}
});
},
deep: true,
},
},
methods: {
// 选中左侧元素
checkLeftElement(val) {
this.leftKey = val.key;
},
// 左侧选中的元素
checkboxLeftChanged(value) {
if (value.checked) {
this.checkLeft.push(value);
} else {
const index = this.checkLeft.findIndex((obj) => obj.key === value.key);
if (index !== -1) {
this.checkLeft.splice(index, 1);
}
}
},
// 右侧选中的元素
checkboxRightChanged(value) {
if (value.checked) {
this.checkRight.push(value);
} else {
const index = this.checkRight.findIndex((obj) => obj.key === value.key);
if (index !== -1) {
this.checkRight.splice(index, 1);
}
}
},
// 向右
turnRight() {
let pushRight = this.checkLeft.map((item) => {
return { ...item, status: true };
});
pushRight.forEach((item) => {
item.checked = false;
if (!this.rightData.some((obj) => obj.key === item.key)) {
this.rightData.push(item);
}
});
this.checkLeft = [];
this.leftData = this.leftData.filter((x) => x["checked"] !== true);
this.$emit("chageRightData", this.rightData);
},
// 向左
turnLeft() {
let modifiedArray = this.checkRight.map((item) => {
const { status, ...rest } = item;
return { ...rest, checked: false };
});
modifiedArray.forEach((item) => {
if (!this.leftData.some((obj) => obj.key === item.key)) {
this.leftData.push(item);
}
});
this.checkRight = [];
this.rightData = this.rightData.filter((x) => x["checked"] !== true);
this.$emit("chageRightData", this.rightData);
},
switchLeftNumber(sourceObj, targetObj) {
const self = this;
const sourceIndex = this.getLeftIndex(sourceObj["key"]);
const targetIndex = this.getLeftIndex(targetObj["key"]);
let arr = JSON.parse(JSON.stringify(this.leftData));
arr[sourceIndex] = targetObj;
arr[targetIndex] = sourceObj;
this.leftData = arr;
},
switchRightNumber(sourceObj, targetObj) {
const self = this;
const sourceIndex = this.getRightIndex(sourceObj["key"]);
const targetIndex = this.getRightIndex(targetObj["key"]);
let arr = JSON.parse(JSON.stringify(this.rightData));
arr[sourceIndex] = targetObj;
arr[targetIndex] = sourceObj;
this.rightData = arr;
// for (const element of this.rightData) {
// if (element["key"] == sourceObj["key"]) {
// console.log("targetObj", element, targetObj);
// // element = targetObj;
// }
// if (element["key"] == targetObj["key"]) {
// console.log("sourceObj", element, sourceObj);
// // element = sourceObj;
// }
// }
},
dragRightToLeft(sourceData, tagetId) {
sourceData.status = false;
if (tagetId & (tagetId != "left")) {
//放到元素上,在此处插入
const targetIndex = this.leftData.findIndex((x) => x["key"] == tagetId);
this.leftData.splice(targetIndex, 0, sourceData);
} else {
//未放到元素上,追加尾部
this.leftData.push(sourceData);
}
this.rightData = this.rightData.filter(
(x) => x["key"] != sourceData["key"]
);
},
dragLeftToRight(sourceData, tagetId) {
sourceData.status = true;
if (tagetId && tagetId != "right") {
//放到元素上,在此处插入
const targetIndex = this.rightData.findIndex(
(x) => x["key"] == tagetId
);
this.rightData.splice(targetIndex, 0, sourceData);
} else {
//未放到元素上,追加尾部
this.rightData.push(sourceData);
}
this.leftData = this.leftData.filter(
(x) => x["key"] != sourceData["key"]
);
},
getDataById(id) {
const dataList = this.data.filter((x) => x["key"] == id);
return dataList ? dataList[0] : {};
},
getRightDataById(id) {
const dataList = this.rightData.filter((x) => x["key"] == id);
return dataList ? dataList[0] : {};
},
getLeftIndex(id) {
return this.leftData.findIndex((x) => x["key"] == id);
},
getRightIndex(id) {
return this.rightData.findIndex((x) => x["key"] == id);
},
getLeftDataById(id) {
const dataList = this.leftData.filter((x) => x["key"] == id);
return dataList ? dataList[0] : {};
},
allowDrop(ev) {
ev.preventDefault();
},
dragstart(ev) {
ev.dataTransfer.setData("id", ev.target.id);
},
drop(ev) {
ev.preventDefault();
debugger;
const source_id = ev.dataTransfer.getData("id");
const targetElement = ev.target.closest("[id]");
const target_id = targetElement ? targetElement.id : "";
if (source_id && target_id) {
const left_source_obj = this.getLeftDataById(source_id);
const left_target_obj = this.getLeftDataById(target_id);
const right_source_obj = this.getRightDataById(source_id);
const right_target_obj = this.getRightDataById(target_id);
if (left_source_obj && (right_target_obj || target_id == "right")) {
//左边-右边
this.dragLeftToRight(left_source_obj, target_id);
} else if (
right_source_obj &&
(left_target_obj || target_id == "left")
) {
//右边-左边
this.dragRightToLeft(right_source_obj, target_id);
} else if (
left_source_obj &&
(left_target_obj || target_id == "left")
) {
//左边调换顺序
this.switchLeftNumber(left_source_obj, left_target_obj);
} else if (
right_source_obj &&
(right_target_obj || target_id == "right")
) {
if (target_id == "right") {
this.rightData = this.rightData.filter(
(x) => x["key"] != right_source_obj["key"]
);
this.rightData.push(right_source_obj);
} else {
//右边调换顺序
this.switchRightNumber(right_source_obj, right_target_obj);
}
}
}
this.$emit("chageRightData", this.rightData);
},
},
};
</script>
<style scoped lang="scss">
.drag-transfer {
margin: 0;
padding: 0;
height: 450px;
}
.tipSapn1 {
display: inline-block;
width: 4px;
height: 14px;
background: #4353e2;
float: left;
margin-right: 6px;
margin-top: 3px;
}
.drag-transfer-title {
font-family: PingFangSC, PingFang SC;
margin-bottom: 18px;
font-weight: 500;
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
font-style: normal;
}
.dragSpan {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 12px;
color: #a6acbd;
line-height: 14px;
text-align: left;
font-style: normal;
}
.drag-transfer-content {
}
.drag-transfer-item {
width: 280px;
height: 368px;
/* width: 260px; */
/* height: 100%; */
background: #fafbfc;
border-radius: 4px;
border: 1px solid #d7e3ff;
overflow-y: auto;
overflow-x: hidden;
}
.drag-transfer-left {
float: left;
height: 400px;
}
.drag-transfer-center {
float: left;
height: 400px;
width: 52px;
}
.drag-transfer-right {
float: left;
height: 400px;
}
.drag-transfer-item-name {
width: 112px;
height: 30px;
background: #ffffff;
border-radius: 2px;
border: 1px solid #dce4f6;
margin-left: 19px;
margin-top: 19px;
float: left;
}
input[type="checkbox"] {
background: #ffffff;
border-radius: 2px;
margin-top: 6px;
float: left;
margin-left: 11px;
margin-right: 7px;
width: 16px;
height: 16px;
}
.checkSpan {
display: inline-block;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 14px;
color: #333333;
line-height: 30px;
text-align: center;
font-style: normal;
}
input[type="checkbox"]::after {
color: #000;
width: 16px;
height: 16px;
display: inline-block;
visibility: visible;
padding-left: 0px;
text-align: center;
content: " ";
border-radius: 2px;
}
input[type="checkbox"]:checked::after {
content: "✓";
color: #fff;
font-size: 14px;
line-height: 17px;
background-color: #4a5de8;
border-radius: 3px;
}
.dragActive {
border-radius: 2px;
border: 1px solid #4353e2;
}
.twoImage {
height: 84px;
margin-top: 168px;
img {
margin-bottom: 28px;
margin-left: 12px;
cursor: pointer;
}
}
</style>