产品需求
如上图,用户点击左侧的“计划员”后,勾选右侧表格中的某几个账户后,继续点击左侧的“安全员”,这时右侧的表格会请求接口刷新数据,用户继续勾选了某几个账户后,再次点击“计划员”后,之前勾选的需要回显并可取消勾选。点击右上角的确定后,选中的所有用户名称展示在下图的 input 框中。
如图所示,考勤人员和考勤组负责人的 input 框 focus 的时候都需要展示表格多选的弹窗,并且在编辑考勤组的时候可以回显。
需求描述完毕,接下来就要开始写代码喽 ^_^
开始撸代码
- 因为要多次使用到多选表格的弹窗,所以需要做成一个单独的组件,选中的数据我们存储到
selectedList中,因为需要回显,所以selectedList需要父组件用props传递过来。
// selectedList 是一个id的list,最终是要提交给后端的
// propSelectedNames 是不需要给后端的,但是我们展示在 input 中的需要名字而不是 id
props: {
selectedList: {
type: Array,
default: () => []
},
propSelectedNames: {
type: Array,
default: () => []
},
},
- 接下来,我们需要给 table 加 select 点击事件
<!-- html 结构 -->
<el-table
:data="tableList"
ref="multipleTable"
@select="onSelect"
>
<el-table-column type="selection" width="55"></el-table-column>
</el-table>
data() {
return {
tableList: [],
totalCount: 0,
selectedIds: new Set(), // set 自动去重
selectedNames: new Set()
};
},
// methods 方法
onSelect(selection, row) {
// 区分是选中 or 取消选中
if (selection.includes(row)) {
this.addSelection(row.id, row.name);
} else {
this.removeSelection(row.id, row.name);
}
},
addSelection(id, name) {
id && this.selectedIds.add(id);
name && this.selectedNames.add(name);
},
removeSelection(id, name) {
this.selectedIds.delete(id);
this.selectedNames.delete(name);
},
- 接下来是重点,处理回显
watch: {
selectedList(val) {
// 清空上一次选择的值
this.selectedIds.clear();
this.selectedNames.clear();
if (val) {
this.selectedList.forEach(i => {
this.addSelection(i);
});
this.propSelectedNames.forEach(i => {
this.addSelection(null, i);
});
}
this.setTableSelection();
}
},
created() {
// 获取表格数据
this.getTableList();
this.selectedList.forEach(i => {
this.addSelection(i);
});
this.propSelectedNames.forEach(i => {
this.addSelection(null, i);
});
},
methods: {
setTableSelection() {
// 每次 table 渲染后都调用一次
this.$nextTick(() => {
// 清空表格的历史勾选项
this.$refs.multipleTable.clearSelection();
const ret = [...this.selectedIds];
ret.forEach(id => {
const item = this.tableList.find(i => i.id === id);
if (item) {
// 回显
this.$refs.multipleTable.toggleRowSelection(item, true);
}
});
});
},
// 获取表格的接口调用
async getTableList() {
const { data } = await xxxTableList(this.searchForm);
this.tableList = data.list || [];
this.totalCount = data.totalCount || 0;
this.setTableSelection();
}
}
- 最后,点击“确定”,把选中的 id & name 传给父组件
methods: {
sureHandle() {
// 把选中的表格人员传递给父组件
this.$emit(
"selectPerson",
[...this.selectedIds],
[...this.selectedNames]
);
this.$emit("close");
},
}
- 最后的最后,父组件中引用子组件,大神止步即可。
<el-dialog
append-to-body
:title="dialogTitle"
:visible="personDialog"
@close="closePerson"
width="80%"
>
<organize-component
:selectedList="selectedList"
:propSelectedNames="propSelectedNames"
@selectPerson="selectPerson"
@close="closePerson"
></organize-component>
</el-dialog>
大功告成 完整demo地址:github.com/fengqijie/m…