element table 多选分页回显

812 阅读2分钟

产品需求

2-掘金.png

如上图,用户点击左侧的“计划员”后,勾选右侧表格中的某几个账户后,继续点击左侧的“安全员”,这时右侧的表格会请求接口刷新数据,用户继续勾选了某几个账户后,再次点击“计划员”后,之前勾选的需要回显并可取消勾选。点击右上角的确定后,选中的所有用户名称展示在下图的 input 框中。

1-掘金.png

如图所示,考勤人员和考勤组负责人的 inputfocus 的时候都需要展示表格多选的弹窗,并且在编辑考勤组的时候可以回显。

需求描述完毕,接下来就要开始写代码喽 ^_^

开始撸代码

  1. 因为要多次使用到多选表格的弹窗,所以需要做成一个单独的组件,选中的数据我们存储到 selectedList 中,因为需要回显,所以 selectedList 需要父组件用 props 传递过来。
// selectedList 是一个id的list,最终是要提交给后端的
// propSelectedNames 是不需要给后端的,但是我们展示在 input 中的需要名字而不是 id

 props: {
  selectedList: {
    type: Array,
    default: () => []
  },
  propSelectedNames: {
    type: Array,
    default: () => []
  },
},
  1. 接下来,我们需要给 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);
},
  1. 接下来是重点,处理回显
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();
    }
}
  1. 最后,点击“确定”,把选中的 id & name 传给父组件
methods: {
    sureHandle() {
      // 把选中的表格人员传递给父组件
      this.$emit(
        "selectPerson",
        [...this.selectedIds],
        [...this.selectedNames]
      );
      this.$emit("close");
    },
}
  1. 最后的最后,父组件中引用子组件,大神止步即可。
<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…