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

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

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

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

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

<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>
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

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现分页的思路大致如下: 1. 在Vue的data中定义一个数组,用于存放分页数据。 2. 在mounted函数中发起请求获取数据,并将数据存放到定义的数组中。 3. 在页面上使用Element-ui的Table组件展示数据,并且使用Pagination组件实现分页功能。 4. 当用户点击分页按钮时,触发pagination的current-change事件,重新请求数据并更新数组中的数据。 以下是一个简单的例子: ``` <template> <div> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> <el-table-column prop="sex" label="性别"></el-table-column> </el-table> <el-pagination @current-change="handlePageChange" :current-page="currentPage" :page-size="pageSize" :total="total"> </el-pagination> </div> </template> <script> import axios from 'axios'; export default { data() { return { tableData: [], currentPage: 1, pageSize: 10, total: 0 }; }, mounted() { this.fetchData(); }, methods: { fetchData() { axios.get('/api/data', { params: { page: this.currentPage, pageSize: this.pageSize } }).then(response => { this.tableData = response.data.list; this.total = response.data.total; }); }, handlePageChange(currentPage) { this.currentPage = currentPage; this.fetchData(); } } }; </script> ``` 在上面的例子中,我们使用了Element-ui的Table和Pagination组件,并且使用axios来发起请求。在mounted函数中,我们调用fetchData函数来获取数据,并将数据存放到tableData数组中。在页面上,我们将tableData数组作为Table组件的data属性传递,展示数据。同时,我们使用Pagination组件来实现分页功能。当用户点击分页按钮时,我们调用handlePageChange函数来更新currentPage变量,并重新调用fetchData函数来获取新的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值