利用el-table的 @selection-change=_handleSelectionChange_实现左右动态显示且表格变化数据仍在
利用el-table的@select-change = handleSelectionChange实现 左侧可控制右侧,右侧也可控制左侧。点搜索显示相应数据,右侧不会被清空,点击右侧X左侧对应勾选的数据会被取消由于列表的改变会触发handleSelectionChange事件,所以为了解决这个问题,需要用一个变量去控制这个状态,上述需求里面除了初始触发,还会有搜索触发的问题只要做到搜索触发时拦截即
·
利用el-table的 @selection-change="handleSelectionChange"实现左右动态显示且表格变化数据仍在
需求:左侧可控制右侧,右侧也可控制左侧。点搜索显示相应数据,右侧不会被清空,点击右侧X左侧对应勾选的数据会被取消
<el-table
class="table-class"
:data="tableData"
stripe
v-loading="tableLoading"
ref="multipleTable"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
align="center"
:width="$store.state.htmlSize * 5"
></el-table-column>
</el-table>
由于列表的改变会触发handleSelectionChange事件,所以为了解决这个问题,需要用一个变量去控制这个状态,上述需求里面除了初始触发,还会有搜索触发的问题只要做到搜索触发时拦截即可。话不多说,代码如下:
<template>
<div class="root">
<el-dialog
:visible="true"
class="dialog-root"
:show-close="false"
:close-on-press-escape="false"
>
<div slot="title" class="dialog-title">
<div class="dialong-text">
<div class="title-icon"></div>
<div class="title-text">关联设备</div>
</div>
<span class="el-icon-close i-close" @click="cancel" title="关闭"></span>
</div>
<div class="dialog-body">
<div class="content">
<div class="item content-left">
<div class="tableRoot">
<!-- 内容区域 -->
<div class="tableContent">
<div class="search-content" ref="searchContent">
<div class="search_main">
<div class="search-item">
<el-select
class="search-inp"
v-model="searchParam.param.devType"
clearable
placeholder="选择类型"
>
<el-option
v-for="item in optionsType"
:key="item.typeCode"
:label="item.typeName"
:value="item.typeCode"
></el-option>
</el-select>
</div>
<div class="search-item">
<el-input
class="search-inp"
v-model="searchParam.param.devName"
clearable
placeholder="输入名称"
></el-input>
</div>
<div class="search-item">
<el-button
class="query-btn"
icon="el-icon-search"
@click="searchTable"
>查 询</el-button
>
</div>
</div>
</div>
<!-- table 区域 -->
<div class="table">
<el-table
class="table-class"
:data="tableData"
stripe
v-loading="tableLoading"
ref="multipleTable"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
align="center"
:width="$store.state.htmlSize * 5"
></el-table-column>
<el-table-column
type="index"
:width="$store.state.htmlSize * 5"
align="center"
show-overflow-tooltip
label="序号"
></el-table-column>
<el-table-column
prop="devTypeName"
align="center"
:formatter="formatterType"
show-overflow-tooltip
label="设备类型"
></el-table-column>
<el-table-column
prop="devName"
align="center"
show-overflow-tooltip
label="设备名称"
></el-table-column>
</el-table>
</div>
</div>
</div>
</div>
<div class="item content-right">
<div class="tableRoot">
<!-- 内容区域 -->
<div class="tableContent">
<div class="search-content" ref="searchContent">
<div class="search_main">
<div class="search-item">
已选择{{ tableDataRight.length }}个设备
</div>
</div>
</div>
<div class="table">
<el-table
class="table-class"
:data="tableDataRight"
stripe
v-loading="tableLoading"
>
<el-table-column
:width="$store.state.htmlSize * 5"
align="center"
:render-header="renderHeader"
>
<template slot-scope="scope">
<div class="delTableItem">
<div
class="delItemIcon"
@click="delItemTable(scope.row)"
>
x
</div>
</div>
</template>
</el-table-column>
<el-table-column
type="index"
:width="$store.state.htmlSize * 5"
align="center"
show-overflow-tooltip
label="序号"
></el-table-column>
<el-table-column
prop="devTypeName"
align="center"
:formatter="formatterType"
show-overflow-tooltip
label="设备类型"
></el-table-column>
<el-table-column
prop="devName"
align="center"
show-overflow-tooltip
label="设备名称"
></el-table-column>
</el-table>
</div>
</div>
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<div class="confirm-btn btn" @click="confirm">确 定</div>
<div class="cancel-btn btn" @click="cancel">取 消</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import Api from "@/api/Api.js";
export default {
props: {
mainDevId: {
type: [String, Number],
default: () => "",
required: true
},
optionsTypeEquip: {
type: Array,
default: () => [],
required: true
}
},
data() {
return {
searchParam: {
current: 1,
size: 9999999,
param: {
devCode: null,
devName: null,
devStatus: null,
devType: null
}
},
tableLoading: false,
tableData: [],
tableDataRight: [],
hasRelatedTableList: [
// {
// devCode: "999999999",
// devTypeName: "模拟已关联设备",
// devName: "测试数据"
// }
],
search: 0, // 1.搜索开始 0搜索结束
value: "",
optionsType: this.optionsTypeEquip,
checkedList: [],
mapListParam: [
{
mainDevId: this.mainDevId, //主设备id
subDevId: "" //关联设备id
}
],
tableDataRightCodes: [], //右侧code集合
leftCodes: [] //左侧列表code集合
};
},
async mounted() {
// 查询已经关联的设备信息 ==> 右侧列表需要显示已经关联的设置的信息
let res = await this.getMapDevices();
// 右侧列表需要显示已经关联的设置的信息
if (res == 0) this.tableDataRight.unshift(...this.hasRelatedTableList);
// 左边表格的原始信息
this.getPages();
},
methods: {
// 已选择的设备需要默认勾选
defaultChoose(arr, tableArr, choose = true) {
/*
注意:这里不能直接遍历arr,element和item 他们在内存中的地址不同,所以他们是两份不同的数据,所以这么写 toggleRowSelection(element, true) 是不会回显选中的
*/
for (let index = 0; index < tableArr.length; index++) {
const item = tableArr[index];
arr.forEach(element => {
if (element.devCode == item.devCode) {
this.$nextTick(() => {
this.$refs.multipleTable.toggleRowSelection(item, choose);
});
}
});
}
},
// 查询已经关联的设备信息
async getMapDevices() {
let res = await Api.device.device.getMapDevices(this.mainDevId);
if (res.code == 0) {
this.hasRelatedTableList = res.data;
}
return res.code;
},
// 表格选中的数组
handleSelectionChange(array) {
if (this.search) return; //解决搜索右侧排序变化的问题
// =================新增的情况====勾选复选框=========
this.tableDataRightCodes = this.tableDataRight.map(dev => dev.devCode);
array.forEach(dev => {
if (this.tableDataRightCodes.indexOf(dev.devCode) < 0) {
this.tableDataRight.push(dev);
}
});
// =================取消选中左侧复选框的情况=============
let changeCodes = array.map(dev => dev.devCode); //拿到当前被选中的全部code
this.tableDataRight = this.tableDataRight.filter(
dev =>
!(
this.leftCodes.indexOf(dev.devCode) >= 0 &&
changeCodes.indexOf(dev.devCode) < 0
)
);
},
// 判断参数里面有没有空值有空值将值改为none
initParamEmpty(obj) {
let arrKeys = Object.keys(obj);
arrKeys.map(v => {
if (!obj[v]) {
obj[v] = null;
}
return v;
});
},
// 查询
searchTable() {
this.initParamEmpty(this.searchParam.param);
this.search = 1;
this.getPages();
},
// 将自己 this.mainDevId 主设备id 的这条数据 删除 因为设备不能关联本身 避免全选出bug 删除最为稳妥
delSelfTable(array) {
for (let index = 0; index < array.length; index++) {
const item = array[index];
if (item.devCode == this.mainDevId) {
array.splice(index, 1);
}
}
return array;
},
getPages() {
Api.device.device.getPages(this.searchParam).then(res => {
if (res.code == 0) {
this.tableData = this.delSelfTable(res.data.data);
this.leftCodes = this.tableData.map(dev => dev.devCode);
this.defaultChoose(this.tableDataRight, this.tableData);
this.$nextTick(() => {
this.search = 0;
});
}
});
},
// 类别格式化
formatterType(row) {
if (row.devTypeName != "unknown") {
return row.devTypeName;
} else {
return "--";
}
},
// 右边表格头部渲染函数
renderHeader(h) {
return h(
"div", // 标签的名称
{
domProps: {
innerHTML:
'<div class="delTableItem"><span class="headerDelTable">x</span></div>'
},
on: {
click: () => {
this.delAllTable();
}
}
},
[h("span")]
);
},
delAllTable() {
this.tableDataRight = [];
this.$refs.multipleTable.clearSelection();
// this.defaultChoose([], this.tableData, false);
},
delItemTable(row) {
// tableDataRight 对应删除这条数据
// 左侧列表也要对应删除这条数据
this.tableDataRight.forEach((item, index) => {
if (item.devCode == row.devCode) {
this.tableDataRight.splice(index, 1);
this.defaultChoose([item], this.tableData, false);
}
});
},
cancel() {
this.$emit("close");
},
confirm() {
// 主设备id和关联设备id不能相同 前期已经做了删除,这里不用判断了
this.mapListParam = [];
this.tableDataRight.forEach(v => {
let obj = {
mainDevId: this.mainDevId, //主设备id
subDevId: v.devCode //关联设备id
};
this.mapListParam.push(obj);
});
this.mapDevices(this.mapListParam);
},
// 关联设备
mapDevices(param) {
Api.device.device.mapDevices(param).then(res => {
if (res.code == 0) {
this.$message.success(res.data);
this.$emit("submit");
}
});
}
}
};
</script>
<style lang="stylus" scoped>
>>>.headerDelTable {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 80px;
background: rgba(52, 89, 157, 0.6);
border-radius: 4px;
cursor: pointer;
padding-bottom: 20px;
}
.dialog-root {
/deep/.el-dialog {
width: 4708px;
height: 2292px;
}
.dialog-body {
width: 4587px;
height: 2050px;
}
.content {
width: 100%;
height: calc(100% - 200px);
padding: 80px;
display: flex;
align-items: center;
justify-content: center;
font-size: 52px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #D3DCFF;
.item {
width: 50%;
height: 100%;
}
.content-left {
border-right: 2px solid rgba(68, 107, 255, 0.4);
}
.content-right {
padding: 30px 0px 0px 60px;
>>>.cell {
> div {
height: 100% !important;
}
}
>>>.delTableItem {
display: flex;
justify-content: center;
align-items: center;
width: 100px;
height: 100%;
border-radius: 4px;
// border:5px solid red;
.delItemIcon {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 80px;
background: rgba(52, 89, 157, 0.6);
border-radius: 4px;
cursor: pointer;
padding-bottom: 20px;
}
}
}
}
.tableRoot {
width: 100%;
height: 100%;
color: #fff;
padding: 0px 60px 40px 0;
.search-inp {
width: 720px;
/deep/.el-input__inner {
width: 100%;
font-size: 52px;
background: rgba(26, 39, 100, 0.6);
border: 2px solid #2D449D;
border-radius: 12px;
}
}
.search-content {
margin-top: 0;
}
.search-content .search_main {
padding: 0;
background: none;
border: 0;
.search-item {
margin-right: 80px;
}
.search-item:last-child {
margin-right: 0;
}
}
.query-btn {
width: 500px;
height: 130px;
}
.table {
background: none;
border: 0;
padding: 0;
// border:5px solid yellow;
.table-class {
width: 100%;
height: 1460px;
overflow-y: scroll;
}
>>>.el-checkbox__inner {
width: 68px;
height: 68px;
transition: none;
border-color: #89c9ff;
border-radius: 8px;
}
>>>.el-checkbox__input.is-checked .el-checkbox__inner::after {
height: 40px;
width: 20px;
left: 18px;
/* top: px; */
border-width: 10px;
border-radius: 10px;
}
>>>.el-checkbox__input.is-indeterminate .el-checkbox__inner::before {
top: 25px;
height: 10px;
}
>>>.el-checkbox {
padding-left: 2px;
}
}
}
}
</style>
更多推荐
已为社区贡献2条内容
所有评论(0)