el-table实现穿梭框、分页、回显功能

1、需求

左边表格是后台返回的数据,你需要实现穿梭框功能
将你选择的数据通过按钮移动到右侧表格
两个表格都能实现分页和数据穿梭、回显(数据回显就是你点击下一页之前的勾选的的状态不丢失)
数据一旦穿梭(移动)这个表格就不会显示这条数据

2、效果展示

el-table实现穿梭框、分页、回显功能_第1张图片
el-table实现穿梭框、分页、回显功能_第2张图片

3、html代码

  <div
              style="display: flex; justify-content: space-evenly"
            >
              <div style="flex: 1">
                <div class="table-title">
                  <span style="color: #ff4949"
                    >备选门店总数:{{ tableDatas.length }}</span
                  >
                </div>
                <div style="width: 98%; margin-top: 5px; height: 100%">
                  <el-table
                    :key="upateCurrentTableKey"
                    ref="storeMultipleTable"
                    tooltip-effect="dark"
                    :data="currentPageData"
                    :height="tableHeight"
                    :row-key="getRowKey"
                    border
                    useVirtual
                    @selection-change="alternateChange"
                  >
                    <el-table-column
                      :selectable="rowSelect"
                      type="selection"
                      width="55"
                      :disabled="isOnlyRead"
                    ></el-table-column>
                    <el-table-column align="center" label="门店编码">
                      <template slot-scope="scope">
                        {{ scope.row.storeNo }}
                      </template>
                    </el-table-column>
                    <el-table-column
                      prop="name"
                      align="center"
                      label="门店名称"
                    />
                  </el-table>
                  <div class="pagination">
                    <el-pagination
                      small
                      @size-change="handleSizeChange"
                      @current-change="handleCurrentChange"
                      :current-page="currentPage"
                      :page-sizes="[100, 200, 300, 400, 500]"
                      :page-size="pageSize"
                      layout="total, sizes, prev, pager, next, jumper"
                      :total="tableDatas.length"
                    ></el-pagination>
                  </div>
                </div>
              </div>
              <div class="btn">
                <el-button
                  type="primary"
                  icon="el-icon-arrow-left"
                  :disabled="rightChooseTable.length > 0 ? false : true"
                  @click="leftChangeTable"
                ></el-button>
                <el-button
                  type="primary"
                  icon="el-icon-arrow-right"
                  :disabled="leftChooseTable.length > 0 ? false : true"
                  @click="rightChangeTable"
                ></el-button>
              </div>
              <div style="flex: 1">
                <div class="table-title">
                  <span style="color: #ff4949"
                    >已选门店总数:{{ alternateTable.length }}</span
                  >
                  <el-button
                    style="margin-left: 10px"
                    type="danger"
                    size="mini"
                    plain
                    :disabled="rightChooseTable.length > 0 ? false : true"
                    @click="deleteChooseData"
                    >批量删除</el-button
                  >
                </div>
                <div style="width: 98%; margin-top: 5px; height: 100%">
                  <el-table
                    :key="upateCurrentTableKey"
                    ref="storeMultipleTable1"
                    tooltip-effect="dark"
                    :data="currentPageData1"
                    :height="tableHeight"
                    :row-key="getRowKey"
                    border
                    useVirtual
                    @selection-change="chooseChange"
                  >
                    <el-table-column
                      :selectable="rowSelect"
                      type="selection"
                      width="55"
                      :disabled="isOnlyRead"
                    ></el-table-column>
                    <el-table-column align="center" label="门店编码">
                      <template slot-scope="scope">
                        {{ scope.row.storeNo }}
                      </template>
                    </el-table-column>
                    <el-table-column
                      prop="name"
                      align="center"
                      label="门店名称"
                    />
                  </el-table>
                  <div class="pagination">
                    <el-pagination
                      small
                      @size-change="handleSizeChange1"
                      @current-change="handleCurrentChange1"
                      :current-page="currentPage1"
                      :page-sizes="[100, 200, 300, 400, 500]"
                      :page-size="pageSize1"
                      layout="total, sizes, prev, pager, next, jumper"
                      :total="alternateTable.length"
                    ></el-pagination>
                  </div>
                </div>
              </div>
            </div>

4、js代码

数据是我自己写死的,到时候你可以发起请求替换数据
代码等有时间再继续优化

 data() {
    return {
      pageSize: 100, // 每页显示的数据条数
      currentPage: 1, // 当前页码
      currentPageData: [], // 当前页的数据

      pageSize1: 100, // 每页显示的数据条数
      currentPage1: 1, // 当前页码
      currentPageData1: [], // 当前页的数据
      
       alternateTable: [],
      chooseTable: [],
      leftChooseTable: [],
      rightChooseTable: [],
      tableDatas: [],
      tableHeight: 406,
      visible: false,
      activeName: "1",
}
}
 created() {
    for (let index = 0; index < 10000; index++) {
      this.tableDatas.push({
        id: index,
        storeNo: "11111111" + index,
        name: "测试",
      });
    }// 手动分页
    this.fetchData();
  },
   methods: {
   // 备选门店
    alternateChange(val) {
      // 循环加入
      val.forEach((item) => {
        this.leftChooseTable.push(item);
      });
      // 去重
      this.leftChooseTable = Array.from(new Set(this.leftChooseTable));
    },
    // 左边数据移动右边
    rightChangeTable() {
      this.alternateTable = [
        ...this.alternateTable,
        ...this.leftChooseTable,
      ].sort((a, b) => a.storeNo - b.storeNo);
      this.currentPageData1 = this.alternateTable;
      // 左侧表格过滤已选门店
      this.tableDatas = this.tableDatas.filter((val) => {
        return !this.leftChooseTable.includes(val);
      });
      // 右侧表格过滤已选门店
      this.currentPageData = this.currentPageData.filter((val) => {
        return !this.leftChooseTable.includes(val);
      });
      this.leftChooseTable = "";
      // 解决移动数据分页渲染问题,手动模拟点击一次
      this.handleCurrentChange1(1);
      this.handleCurrentChange(1);
    },
    // 已选门店
    chooseChange(val) {
      val.forEach((item) => {
        this.rightChooseTable.push(item);
      });
      // 去重
      this.rightChooseTable = Array.from(new Set(this.rightChooseTable));
    },
    // 右边数据移动左边
    leftChangeTable() {
      this.currentPageData1 = this.currentPageData1.filter((val) => {
        return !this.rightChooseTable.includes(val);
      });
      this.alternateTable = this.alternateTable.filter((val) => {
        return !this.rightChooseTable.includes(val);
      });
      // 将数据整合并排序
      this.currentPageData = [
        ...this.currentPageData,
        ...this.rightChooseTable,
      ].sort((a, b) => a.storeNo - b.storeNo);
      this.tableDatas = [...this.tableDatas, ...this.rightChooseTable].sort(
        (a, b) => a.storeNo - b.storeNo
      );
      this.rightChooseTable = "";
      // 解决移动数据分页渲染问题,手动模拟点击一次
      this.handleCurrentChange(1);
      this.handleCurrentChange1(1);
    },

    // 批量删除
    deleteChooseData() {
    
      this.leftChangeTable();
    },
    // 左边分页列表
    fetchData() {
      // 这里可以根据实际情况,通过异步请求获取数据
      // 假设我们已经将10000条数据存储在tableDatas中
      this.currentPageData = this.tableDatas.slice(
        (this.currentPage - 1) * this.pageSize,
        this.currentPage * this.pageSize
      );
    },
    handleSizeChange(val) {
      this.pageSize = val;
      this.currentPageData = this.tableDatas.slice(
        (this.currentPage - 1) * this.pageSize,
        this.currentPage * this.pageSize
      );
    },
    handleCurrentChange(val) {
      this.currentPage = val;
      this.currentPageData = this.tableDatas.slice(
        (this.currentPage - 1) * this.pageSize,
        this.currentPage * this.pageSize
      );
      // 回显选中的数据
      this.$nextTick(() => {
        this.currentPageData.forEach((item) => {
          if (this.leftChooseTable.includes(item)) {
            this.$refs.storeMultipleTable.toggleRowSelection(item, true);
          }
        });
      });
      this.$refs.storeMultipleTable.bodyWrapper.scrollTop = 0;
    },
    // 右边分页列表
    handleSizeChange1(val) {
      this.pageSize1 = val;
      this.currentPageData1 = this.alternateTable.slice(
        (this.currentPage1 - 1) * this.pageSize1,
        this.currentPage1 * this.pageSize1
      );
    },
    handleCurrentChange1(val) {
      this.currentPage1 = val;
      this.currentPageData1 = this.alternateTable.slice(
        (this.currentPage1 - 1) * this.pageSize1,
        Math.min(this.currentPage1 * this.pageSize1, this.alternateTable.length)
      );
      // 回显选中的数据
      this.$nextTick(() => {
        this.currentPageData1.forEach((item) => {
          if (this.rightChooseTable.includes(item)) {
            this.$refs.storeMultipleTable1.toggleRowSelection(item, true);
          }
        });
      });
      this.$refs.storeMultipleTable1.bodyWrapper.scrollTop = 0;
    },
   }

5、css部分

.pagination {
  display: flex;
  justify-content: flex-end;
  padding: 10px;
}
.btn {
  display: flex;
  align-items: center;
  padding: 0 20px;
}
.table-title {
  height: 40px;
  font-weight: bold;
  display: flex;
  align-items: center;
}

你可能感兴趣的:(前端)