• vue2.0 + element ui 实现表格穿梭框


    element ui 官网里介绍了穿梭框(Transfer),但在实际使用过程中,会出现一些问题:

    1.穿梭框里能放置的内容太少,不能满足复杂的业务需求。

    2.当选项过多时,穿梭框很难实现分页,左右两个框的分页是联动的,左边翻页了右边也会跟着翻页。若要取消这种关联关系,可参考这篇文章: https://www.cnblogs.com/alice-bj/articles/10703903.html#_label4

    本文参考了穿梭框的实现思路,实现了可分页的表格穿梭框,同时涉及到了表格多选与表格里添加表单等知识点。

    html结构:

    <el-form :inline="true" :model="staffTemp">
        <el-form-item label="手机号">
            <el-input v-model="staffTemp.phone"></el-input>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="getStaffList">查找</el-button>
        </el-form-item>
    </el-form>
    <el-row :gutter="20">
        <el-col :span="11">
            <el-table
                ref="staffTable"
                v-loading="listLoading"
                :key="tableKey"
                :data="staffList"
                border
                fit
                highlight-current-row
                @selection-change="handleStaffChange"
            >
                <el-table-column type="selection" :reserve-selection="true" width="55"></el-table-column>
                <el-table-column label="手机" align="center">
                  <template slot-scope="{row}">
                    <span>{{ row.phone }}</span>
                  </template>
                </el-table-column>
    
                <el-table-column label="昵称" align="center">
                  <template slot-scope="{row}">
                    <span>{{ row.nickName }}</span>
                  </template>
                </el-table-column>
            </el-table>
        </el-col>
        <el-col :span="2" style="text-align:center;">
            <el-button
                @click="addStaff"
                type="primary"
                :disabled="!staffData.length"
                icon="el-icon-arrow-right"
                circle
            ></el-button>
            <el-button
                @click="removeStaff"
                type="primary"
                :disabled="!selectedStaffData.length"
                icon="el-icon-arrow-left"
                circle
                style="margin-left: 0;margin-top: 10px;"
            ></el-button>
        </el-col>
        <el-col :span="11">
            <el-table
                ref="selectedStaffTable"
                v-loading="listLoading"
                :key="tableKey"
                :data="selectedStaffList"
                border
                fit
                highlight-current-row
                @selection-change="handleSelectedStaffChange"
              >
                <el-table-column type="selection" :reserve-selection="true" width="55"></el-table-column>
                <el-table-column label="手机" align="center">
                  <template slot-scope="{row}">
                    <span>{{ row.phone }}</span>
                  </template>
                </el-table-column>
    
                <el-table-column label="昵称" align="center">
                  <template slot-scope="{row}">
                    <span>{{ row.nickName }}</span>
                  </template>
                </el-table-column>
    
                <el-table-column label="类型" align="center">
                  <template slot-scope="{row}">
                    <el-select class="filter-item" placeholder="请选择" v-model="row.staffTypeId">
                      <el-option
                        v-for="item in staffOptions"
                        :key="item.key"
                        :label="item.display_name"
                        :value="item.key"
                      ></el-option>
                    </el-select>
                  </template>
                </el-table-column>
            </el-table>
        </el-col>
    </el-row>

     js部分:

    data() {
      return {
        listLoading: true,
        staffTemp: {
            phone: "",
            nickName: "",
            staffTypeId: ""
          },
        staffList: [],
        selectedStaffList: [],
        staffData: [],
        selectedStaffData: [],
        tableKey: 0,
        rowKey: "rowKey",
        staffOptions: [
            { key: 28, display_name: "补货员" },
            { key: 29, display_name: "测试员" }
          ],
      }
    },
    methods: {
        // 从后台获取左边表格的数据
        getStaffList() {
          fetchStaffList(this.staffTemp).then(res => {
            if (res.value.staff.length === 0) {
              alert("查无此人");
            }
            this.staffList = res.value.staff;
          });
        },
        // 将左边表格选择项存入staffData中
        handleStaffChange(rows) {
          this.staffData = [];
          if (rows) {
            rows.forEach(row => {
              if (row) {
                this.staffData.push(row);
              }
            });
          }
        },
        // 左边表格选择项移到右边
        addStaff() {
          setTimeout(() => {
            this.$refs["staffTable"].clearSelection();
            this.$refs["selectedStaffTable"].clearSelection();
          }, 0);
          let repeat = false;
          this.selectedStaffList.forEach(item => {
            if (this.staffData[0] && item.phone === this.staffData[0].phone) {
              repeat = true;
              alert("此员工已添加");
              return;
            }
          });
          if (repeat === false) {
            this.staffData.forEach(item => {
              this.selectedStaffList.push(item);
            });
            for (let i = 0; i < this.staffList.length; i++) {
              for (let j = 0; j < this.staffData.length; j++) {
                if (
                  this.staffList[i] &&
                  this.staffData[j] &&
                  this.staffList[i].phone === this.staffData[j].phone
                ) {
                  this.staffList.splice(i, 1);
                }
              }
            }
          }
        },
        // 右边表格选择项移到左边
        removeStaff() {
          setTimeout(() => {
            this.$refs["staffTable"].clearSelection();
            this.$refs["selectedStaffTable"].clearSelection();
          }, 0);
          this.selectedStaffData.forEach(item => {
            this.staffList.push(item);
          });
          for (let i = 0; i < this.selectedStaffList.length; i++) {
            for (let j = 0; j < this.selectedStaffData.length; j++) {
              if (
                this.selectedStaffList[i] &&
                this.selectedStaffData[j] &&
                this.selectedStaffList[i].phone === this.selectedStaffData[j].phone
              ) {
                this.selectedStaffList.splice(i, 1);
              }
            }
          }
        },
        // 将右边表格选择项存入selectedStaffData中
        handleSelectedStaffChange(rows) {
          this.selectedStaffData = [];
          if (rows) {
            rows.forEach(row => {
              if (row) {
                this.selectedStaffData.push(row);
              }
            });
          }
        },
        // 提交
        modifyStaff() {
          let isEmpty = false;
          this.selectedStaffList.forEach(item => {
            if (!item.staffTypeId) {
              alert("请选择类型");
              isEmpty = true;
              return;
            }
          });
          if (isEmpty === false) {
            editStaff(this.selectedStaffList, this.deviceQuery.id).then(res => {
              this.staffListVisible = false;
              this.$notify({
                title: "成功",
                message: "修改成功",
                type: "success",
                duration: 2000
              });
            });
          }
        }
    }

    多选表格:手动添加一个 el-table-column,设type属性为 selection 即可;当选择项发生变化时会触发 selection-change 事件,并将选择项作为参数传入。在这里,我们将左边表格的选择项缓存在staffData中,右边表格的选择项缓存在 selectedStaffData 中。

    在移动选择项时,一是要将自身的该项删除,二是要将该项放入对方列表中(需要去重)。

    关于分页功能可在左右两个表格分别添加,互不影响,具体可参考我之前的博客 https://www.cnblogs.com/zdd2017/p/11153527.html

  • 相关阅读:
    Scrum框架及其背后的原则(上)——Scrum 框架的伪代码描述[转载自InfoQ]
    用程序给闺女出算数题——我的头脑体操
    敏捷实践调查结果[翻译转载]
    一.初识Selenium
    二.Selenium安装相关文件
    Review of American Beauty(unoriginal)
    三.Selenium IDE学习
    将Java Project转变为Dynamic Web Project
    功能自动化工具watiJ(转载)
    Selenium前奏
  • 原文地址:https://www.cnblogs.com/zdd2017/p/11188307.html
Copyright © 2020-2023  润新知