效果图
实现代码
直接上代码:
// An highlighted block
<template>
<el-dialog
:visible="true"
title="业务分组"
style="font-size: 18px"
width="900px"
:close-on-click-modal="false"
@close="dialogYwfzShowsBtn"
>
<div>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row :gutter="24">
<el-col :xl="12" :lg="8" :md="12">
<el-form-item label="分组名称" label-width="80px" prop="groupName">
<el-input v-model="form.groupName"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="level">
<!-- 左边框框 -->
<div class="transferbox">
<div class="topbox">
<span>未选择通道</span>
</div>
<div class="level searchbox">
<el-input
v-model="filter"
placeholder="请输入内容"
style="width: 300px"
/>
<el-button
type="primary"
style="margin: 0 0 0 20px"
@click="searchClick"
>搜索</el-button
>
</div>
<div class="contont">
<el-tree
:data="orgData"
:load="getOrgs"
:props="defaultProps"
:expand-on-click-node="false"
:highlight-current="true"
show-checkbox
node-key="id"
ref="tree"
lazy
@check-change="handleCheckChange"
v-show="showTree"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>
{{ node.label }}
</span>
</span>
</el-tree>
<el-checkbox
:indeterminate="isIndeterminate"
v-model="checkAll"
@change="handleCheckAllChange"
v-if="showCheck"
>全选</el-checkbox
>
<div style="margin: 15px 0"></div>
<el-checkbox-group
v-model="checkedCities"
@change="handleCheckedCitiesChange"
>
<el-checkbox
v-for="(item, index) in list"
:label="item.id"
:key="index"
>{{ item.channelName }}</el-checkbox
>
</el-checkbox-group>
</div>
</div>
<!-- 中间按钮 -->
<div class="vertical center3 centrebtn">
<el-button
type="primary"
icon="el-icon-caret-right"
@click="singleSel()"
/>
<el-button
type="primary"
style="margin: 20px 0 0 0"
icon="el-icon-caret-left"
@click="mutiSel()"
/>
</div>
<!-- 右边框框 -->
<div class="transferbox">
<div class="topbox">
<span>已选择通道</span>
</div>
<div style="padding: 10px" class="contont">
<el-checkbox
:indeterminate="isIndeterminateThen"
v-model="checkAllThen"
@change="handleCheckAllChangeThen"
>全选</el-checkbox
>
<div style="margin: 15px 0"></div>
<el-checkbox-group
v-model="checkedCitiesThen"
@change="handleCheckedCitiesChangeThen"
>
<el-checkbox
v-for="(item, index) in selectedData"
:label="item.id"
:key="index"
>{{ item.channelName }}</el-checkbox
>
</el-checkbox-group>
</div>
</div>
</div>
</div>
<div class="dialog-footer">
<el-button class="g-background00BCD4" @click="dialogYwfzShowsBtn"
>返 回</el-button
>
<el-button class="g-background00BCD4" type="primary" @click="onClickSave"
>保存</el-button
>
</div>
</el-dialog>
</template>
<script>
import _ from "underscore";
import $ from "jquery";
const defaultListQuery = {
SkipCount: 0,
MaxResultCount: 20,
};
export default {
name: "PerformTaskDetailDialog",
props: {
visible: Boolean,
id: String,
},
data() {
return {
defaultProps: {
children: "children",
label: "name",
isLeaf: (data, node) => {
return !data.hasChildren;
},
},
checkAllThen: false,
checkedCitiesThen: [],
isIndeterminateThen: true,
checkAllDeatilListThen: [],
checkAll: false,
checkedCities: [],
isIndeterminate: true,
checkAllDeatilList: [],
parentId: null,
listLoading: false,
list: [],
listQuery: Object.assign({}, defaultListQuery),
filter: "",
orgData: [],
checkedArr: [],
showCheck: false,
showTree: true,
selectedData: [],
checkedIDArray: [],
form: {
groupName: "",
},
//form校验
rules: {
groupName: [
{
required: true,
message: "请输入分组名称",
trigger: "blur",
},
],
},
};
},
computed: {
},
watch: {
},
created() {},
mounted: function () {},
methods: {
/* 组织树数据获取*/
getOrgs(node, resolve) {
const params = {};
if (typeof node !== "object") {
if (node) {
params["filter"] = node;
}
} else if (node.level !== 0) {
this.parentId = node.data.id;
}
setTimeout(() => {
//接口请求,根据实际开发设置
this.$api.getUVxxxParentId(this.parentId).then((response) => {
if (resolve) {
resolve(response);
} else {
this.orgData = response;
}
});
}, 100);
},
/* checkbox列表数据获取 */
getList() {
this.listLoading = true;
this.list = [];
this.listQuery.filter = this.filter;
this.$api
.querxxxannels(this.listQuery)
.then((response) => {
this.list = [...response.items];
this.listLoading = false;
})
.catch(() => {
this.listLoading = false;
});
},
searchClick() {
//如果input输入框有值就显示
if (this.filter != "") {
this.showCheck = true;
this.showTree = false;
this.getList();
} else {
this.showCheck = false;
this.showTree = true;
// this.getOrgs();
}
},
//树变化事件
handleCheckChange() {
//获取树选中的所以数据
let res = this.$refs.tree.getCheckedNodes();
//获取树选中的id
this.checkedIDArray = this.$refs.tree.getCheckedKeys();
var nodes = _.filter(res, function (item) {
return !item.hasChildren;
});
this.checkedArr = [];
nodes.forEach((item) => {
item.channelName = item.name;
this.checkedArr.push(item);
});
},
//关闭弹框
dialogYwfzShowsBtn() {
this.$emit("onclose");
},
// 左移
singleSel() {
let self = this;
let queryAreaIdsList = [];
if (self.showCheck == true) { //判断如果checkbox列表就移动checkbox选中的数据
if (this.checkAllDeatilList.length == 0) {
this.$message({
message: "请选择通道!",
type: "warning",
});
return;
}
this.selectedData = [...this.selectedData, ...this.checkAllDeatilList];
} else if (self.showTree == true) { //判断如果el-tree就移动el-tree选中的数据
if (this.checkedIDArray.length == 0) {
this.$message({
message: "请选择通道!",
type: "warning",
});
return;
}
let params = {
areaIds: this.checkedIDArray,
};
//这是我的项目需求,多调用了一次接口,如果是从树直接获取数据,可以忽略接口请求
this.$api.getxxxByOrgIds(params).then((response) => {
queryAreaIdsList = response;
self.selectedData = [...queryAreaIdsList, ...this.checkedArr];
self.selectedData = self.fn2(self.selectedData);
});
}
//self.selectedData = [...this.checkedArr];
//self.selectedData = self.fn2(self.selectedData);
this.selectedData = self.fn2(self.selectedData);
},
//数组去重
fn2(arr) {
const res = new Map();
return arr.filter((arr) => !res.has(arr.id) && res.set(arr.id, arr.id));
},
// 右移
mutiSel() {
//删除选中的
for (let i = 0; i < this.selectedData.length; i++) {
for (let j = 0; j < this.checkedCitiesThen.length; j++) {
if (this.selectedData[i].id == this.checkedCitiesThen[j]) {
this.selectedData.splice(i, 1);
}
}
}
this.isIndeterminateThen = true;
this.checkedCitiesThen = [];
},
//左边未选中
handleCheckAllChange(val) {
let checkAll = [];
if (val) {
for (let i = 0; i < this.list.length; i++) {
checkAll.push(this.list[i].id);
}
}
this.checkAllDeatilList = val ? this.list : [];
this.checkedCities = val ? checkAll : [];
this.isIndeterminate = false;
},
//左边未选中
handleCheckedCitiesChange(value) {
this.checkAllDeatilList = [];
let checkedCount = value.length;
this.checkedCities = value;
this.checkAll = checkedCount === this.list.length;
this.isIndeterminate =
checkedCount > 0 && checkedCount < this.list.length;
//将获取的checkbox的值放到一个数组里
for (let i = 0; i < this.list.length; i++) {
for (let j = 0; j < this.checkedCities.length; j++) {
if (this.list[i].id == this.checkedCities[j]) {
this.checkAllDeatilList.push(this.list[i]);
}
}
}
},
//右边已选中通道
handleCheckAllChangeThen(val) {
let checkAll = [];
if (val) {
for (let i = 0; i < this.selectedData.length; i++) {
checkAll.push(this.selectedData[i].id);
}
}
this.checkedCitiesThen = val ? checkAll : [];
this.isIndeterminateThen = false;
},
//右边已选中通道
handleCheckedCitiesChangeThen(value) {
this.checkAllDeatilListThen = [];
let checkedCount = value.length;
this.checkAllThen = checkedCount === this.selectedData.length;
this.isIndeterminateThen =
checkedCount > 0 && checkedCount < this.selectedData.length;
},
onClickSave() {
this.$refs.form.validate((valid) => {
if (valid) {
if (this.selectedData.length == 0) {
this.$message({
message: "通道不能为空!",
type: "warning",
});
return;
}
let channelObjIds = [];
this.selectedData.forEach((item, index) => {
channelObjIds.push(item.objId);
});
let params = {
groupName: this.form.groupName,
channelObjIds: channelObjIds,
};
//保存接口,根据实际开发需要定义
this.$api.createxxxGroup(params).then((response) => {
if (response.success) {
this.$message({
message: "业务分组保存成功。",
type: "success",
});
this.$emit("onclose", true);
} else {
this.$message({
message: response.info,
type: "warning",
});
this.$emit("onclose", false);
}
});
}
});
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-dialog {
margin-top: 4vh !important;
}
::v-deep .el-dialog__body {
padding: 20px;
}
.detail-row {
margin-bottom: 25px;
.detail {
border-left: solid #ccc 1px;
::v-deep .el-form-item {
margin: 0;
background: #f7f7f7;
label {
padding: 5px 8px;
border-top: solid #ccc 1px;
}
.el-form-item__content {
padding-left: 8px;
padding-top: 5px;
background: white;
border-left: solid #ccc 1px;
border-top: solid #ccc 1px;
}
}
}
.detail.row-end ::v-deep .el-form-item__content {
border-right: solid #ccc 1px;
}
.detail.row-bottom {
border-bottom: solid #ccc 1px;
}
}
.dialog-footer {
padding-top: 20px;
text-align: right;
border-top: solid #eee 1px;
}
///@at-root
///
.transferbox {
height: 600px;
width: 45%; //右边盒子的宽占比
border: 1px solid#ebedf2;
.topbox {
border-bottom: 1px solid #ebedf2;
padding: 10px 10px;
color: #575962;
font-size: 16px;
font-weight: 550;
}
.searchbox {
margin: 10px;
}
}
.centrebtn {
width: 80px;
height: 600px;
margin: 0 10px 0 10px;
color: #ffff;
}
/* 水平居中 */
.center1 {
display: flex;
justify-content: center;
}
/* 垂直水平居中 */
.center3 {
display: flex;
align-items: center;
justify-content: center;
}
/* 水平布局 */
.level {
display: flex;
flex-direction: row;
}
// 垂直布局
.vertical {
display: flex;
flex-direction: column;
}
.contont {
padding: 10px;
}
::v-deep .contont .el-checkbox {
display: block;
}
</style>
这是弹框页面,可以当做组件调用,也可以根据实际开发需求自定义自己的页面。只要树的数据和checkbox的数据自己定义好,就可以直接复用。