一、需求描述
el-table嵌在一个el-dialog中作为一个子组件,该子组件主要包括两个内容:已选择列表和表格(可分页),已选择列表和表格可以动态联动,也即表格勾选或取消勾选一项,已选择列表会相应增加或减少一项;已选择列表删除一项,表格的勾选状态也会改变。
弹窗打开时,已选择列表和表格的多选状态都会有一个初始值,子组件接收从父组件获取的值,将其赋给selectList,已选择列表展示selectList内容,同时表格根据selectList设置表格的初始勾选状态。
同时,切换分页时可以保持表格的勾选状态。
二、实现步骤
1、页面数据
<div v-if="selectList.length">
<div v-for="item in selectList" :key="item.id">
<span>{{ item.userName }}</span>
<i class="el-icon-close" @click="delSelect(item.id)"></i>
</div>
</div>
<el-table
ref="multipleTable"
:data="tableData"
:border="true"
@select="handleSelectionChange"
@select-all="handleAllChange"
>
<el-table-column type="selection" width="55" align="center">
</el-table-column>
</el-table>
<el-pagination
background
layout="->,prev, pager, next"
prev-text="上一页"
next-text="下一页"
:page-size="pageNum"
:total="total"
:current-page.sync="current"
@current-change="handleCurrentChange"
>
data() {
return {
tableData: [], //当前页的表格数据
selectList: [], //所有已选择选项
}
}
2、监听父组件值的改变,设置表格初始状态
watch: {
//监听父组件选择值
addPhones: {
handler(val) {
this.$nextTick(() => {
this.selectList =val;
this.changeState();
});
},
immediate: true,
},
//监听表格数据
pushUserList: {
handler(val) {
if (val) {
this.tableData = val;
this.$nextTick(() => {
this.changeState();
});
}
},
immediate: true,
},
}
changeState() {
if (this.$refs.multipleTable) {
if (selectAllIds.length) {
for (let i = 0; i < this.tableData.length; i++) {
if (selectAllIds.indexOf(this.tableData[i]["id"]) >= 0) {
this.$refs.multipleTable.toggleRowSelection(
this.tableData[i],
true
);
}
}
}
}
},
//其中selectAllIds为一个计算属性
computed: {
selectAllIds() {
return this.selectList.map((item) => {
return item.id;
});
},
},
3、表格勾选与已选择列表的动态联动
// 打勾或取消
handleSelectionChange(selecteds, row) {
if (!this.selectAllIds.includes(row.id)) {
this.selectList.push(row);
} else {
this.selectAllIds.forEach((id, index) => {
if (id === row.id) {
this.selectList.splice(index, 1);
}
});
}
},
// 全选、取消全选
handleAllChange(selecteds) {
if (selecteds.length > 0) {
selecteds.forEach((item) => {
if (!this.selectAllIds.includes(item.id)) {
this.selectList.push(item);
}
});
} else {
this.tableData.forEach((item) => {
this.selectAllIds.forEach((id, index) => {
if (id === item.id) {
this.selectList.splice(index, 1);
}
});
});
}
},
//已选择列表删除
delSelect(id) {
this.selectList = this.selectList.filter((item) => {
return item.id !== id;
});
this.$refs.multipleTable.selection.forEach((item, index) => {
if (item.id === id) {
this.$refs.multipleTable.selection.splice(index, 1);
}
});
},
三、注意事项
1、在设置表格初始状态时,必须设置nextTick(),否则不会生效;
2、切换表格勾选状态最好使用select和select-all事件,避免使用selection-change事件,否则会导致设置初始状态时,自动调用该事件的方法,可能出现与预期效果冲突的情况;
3、避免使用row-key 和 reserve-selection ,否则导致自己管理的勾选状态与el-table自身保存的勾选状态互相冲突,状态难以管理。