数组去重实现类似ElementUI穿梭框

这是我参与更文挑战的第6天,活动详情查看: 更文挑战

前言

最近在项目开发中使用到了一个类似穿梭框的操作,再次记录下。主要的功能就是讲左边表格里面的数据通过筛选后放到右边表格,右边表格通过操作后进行相应的其他操作。

分析

其实这个看起来和穿梭框很像,但穿梭框没法做出这样,所以不用想,只能自己动手实现,没有相应的可以直接使用的。其实就是两个表格进行操作,最重要的就是数据在从左到右的时候对数据进行比对,有的不管,没有的插入即可。

实现

布局和结构

这里就不做详细的布局了,就是一个左中右三列的布局,可选的还是很多,float、flex、table布局等等。这里为了节省使用flex布局,布局颜色和结构如下:

<div class="transfer">
  <div class="target">
    <el-table ref="targetTable" :data="targetData" border @selection-change="handleTargetChange">
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column prop="date" label="日期"></el-table-column>
      <el-table-column prop="name" label="姓名"></el-table-column>
    </el-table>
  </div>
  <div class="operate">
    <el-button type="primary" icon="el-icon-d-arrow-right" @click="toDistTable"></el-button>
    <el-button type="primary" icon="el-icon-d-arrow-left" @click="toTargetTable"></el-button>
  </div>
  <div class="dist">
    <el-table ref="distTable" :data="distData" border @selection-change="handleDistChange">
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column prop="date" label="日期"></el-table-column>
      <el-table-column prop="name" label="姓名"></el-table-column>
      <el-table-column label="收入">
        <template slot-scope="scope">
          <el-input v-model="scope.row.award" placeholder="请输入收入"></el-input>
        </template>
      </el-table-column>
    </el-table>
  </div>
</div>

![1.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/87d755ba27d741a2a9bef8dfdbaad1a2~tplv-k3u1fbpfcp-watermark.image)
// style
.transfer{
  display: flex;
  .target{
    width: 48%;
  }
  .operate{
    width: 4%;
    .el-button{
      margin: 0;
    }
  }
  .dist{
    width: 48%;
  }
}
复制代码

基本的数据和表格的操作

data(){
  return {
    targetData:[{id:1,date:'2021-6-27',name:'张三1'},{id:2,date:'2021-6-27',name:'张三2'},{id:3,date:'2021-6-27',name:'张三3'},{id:4,date:'2021-6-27',name:'张三4'},{id:5,date:'2021-6-27',name:'张三5'},{id:6,date:'2021-6-27',name:'张三6'},{id:7,date:'2021-6-27',name:'张三7'},{id:8,date:'2021-6-27',name:'张三8'}],
    distData:[],
    targetSelects:[],
    distSelects:[]
  }
},
methods:{
  handleTargetChange(items){
    this.targetSelects = items
  },
  handleDistChange(items){
    this.distSelects = items
  },
  toDistTable(){},
  toTargetTable(){}
}
复制代码

上面的数据中target相关的为左边表格、dist相关的为右边表格的,然后就是左边和右边表格的选择事件以及选中的数据

现在最为重要的就是实现toDistTable和toTargetTable两个方法。要实现这两个方法其实也很简单,就是讲左边选择的数据循环的去比对右边表格的数据中是否存在。当前我们知道这样是肯定可以实现的,但是有没有更为简洁一点的呢。

数组去重

其实这里的两个table数据进行操作其实就是对两个数组进行操作,那这里我们是否会突然想到之前面试的时候经常会问到的问题数组去重,这里如果使用数组去重的话是否会简洁一点。

选中移动到模板表格

那么有了上面的思路,接下来就是实现了,先来实现toDistTable这个方法,其实就是讲左边选中的数据放入到右边表格中,这里有两个点要注意:首先就是右边没有任何数据的时候,这个时候最简单了,直接就是讲选中的数据放入到右边表格就行,代码如下:

if(this.targetSelects.length){
  if(this.distData.length){
  }else{
    this.distData = this.targetSelects
  }
  this.targetSelects = []
  this.$refs.targetTable.clearSelection()
}
复制代码

上面的代码中如果进行了左边移动到右边就将左边的选中的数据清空

这个时候第一步操作就算完成了,接下来就是第二步如果右边表格有数据了,上面也说了就是利用数组去重来实现,代码如下:

toDistTable(){
  if(this.targetSelects.length){
    if(this.distData.length){
      // 数组去重,去掉已经选中的项
      var list2 = this.targetSelects,list1 = this.distData
      var result = list2.filter(function(coupon) {
          return list1.every(function(item) {
            return item.id !== coupon.id
          })
      })
      this.distData = list1.concat(result)
    }else{
      this.distData = this.targetSelects
    }
    this.targetSelects = []
    this.$refs.targetTable.clearSelection()
  }
}
复制代码

这样我们就实现了左边选中直接放入到右边了。如果大家理解了这里代码,那从右边往左边就和这个差不多了,不过这里呢,对于我自己本身的项目而言,是不需要将右边选中数据放入到左边的,只需要将右边数据删除即可,所以如果想要将右边数据放回左边其实和上面差不多,这里就不做过多介绍,希望大家能够自己动手去实现,右边操作的代码如下:

toTargetTable(){
  if(this.distSelects.length){
    var list2 = this.distData,list1 = this.distSelects
    var result = list2.filter(function(coupon) {
        return list1.every(function(item) {
          return item.id !== coupon.id
        })
    })
    this.distData = result
    this.$refs.distTable.clearSelection()
  }
}
复制代码

总结

到这里就实现了这样一个简单的需求,其实运用的知识点就是数组去重,所有有的时候咋们的基础还是很重要的。谢谢大家!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享