封装一个穿梭框组件

204 阅读2分钟

起初看到这个需求我是很高兴的,因为公司有现成的穿梭框组件,拿来即用!无奈需求有点特殊,只得上手封装!那好吧,不就是个穿梭框嘛,能奈我何!

要说穿梭框,最难的是点击上下穿梭的那部分功能实现。我一开想的是上下两个数组,点击上下穿梭,无非是就是增删数据:点击向下穿梭:删掉上面数组的数据,然后塞下面数组的里面去。一番尝试之后,发现有点棘手,我如何控制它的顺序呢?如果数据量比较大,增删数据会不会造成性能问题呢......

几番纠结之后,我跑去请求上个项目组的同事,他的一句话点醒了,我不记得怎么说的了,大意是:穿梭框你可以用一个数组,然后上下穿梭的时候,把数据显示或隐藏。也就是说,本质上不需要做增删操作,只是改变数组对象的某个属性,控制它的显示与隐藏。听完如醍醐灌顶,我激动得久久不能自拔......真的,多请教听听别人思路,真的会意想不到呢!因为我一开始就掉进了一个棘手的误区,若不是问了这位同事,估计这会还在坑里没爬起来呢!

感叹之余,开始着手封装,真的很哇塞呀!

<template>
  <div>
    <!-- 可选框区域 -->
    <el-table
      ref="optional"
      :data="optionalTableData"
      border
      height="250"
      show-summary
    >
      <el-table-column type="selection" width="80px"> </el-table-column>
      <el-table-column
        v-for="item in tableColumn"
        :key="item.prop"
        :prop="item.prop"
        :label="item.label"
      >
      </el-table-column>
    </el-table>
    <!-- 按钮上下穿梭区域 -->
    <div class="btns">
      <el-button
        type="primary"
        icon="el-icon-arrow-down"
        @click="transferFn('down')"
      ></el-button>
      <el-button
        type="primary"
        icon="el-icon-arrow-up"
        @click="transferFn('up')"
      ></el-button>
    </div>
    <!-- 已选框区域 -->
    <el-table
      ref="selected"
      :data="selectedTableData"
      border
      height="250"
      show-summary
    >
      <el-table-column type="selection" width="80px"></el-table-column>
      <el-table-column
        v-for="item in tableColumn"
        :key="item.prop"
        :prop="item.prop"
        :label="item.label"
      >
      </el-table-column>
    </el-table>
  </div>
</template>
<script>
export default {
  name: 'TransferTable',
  data() {
    return {
      tableData: [
        {
          supplierCode: 'C13361',
          invoiceNo: 'NO123458',
          invoiceNum: '200',
          showArea: 'optional',
        },
        {
          supplierCode: 'J18882',
          invoiceNo: 'NO123459',
          invoiceNum: '500',
          showArea: 'optional',
        },
        {
          supplierCode: 'D44524',
          invoiceNo: 'NO123460',
          invoiceNum: '430',
          showArea: 'optional',
        },
        {
          supplierCode: 'G44236',
          invoiceNo: 'NO123461',
          invoiceNum: '100',
          showArea: 'selected',
        },
      ],
      tableColumn: [
        {
          label: '供应商编码',
          prop: 'supplierCode',
        },
        {
          label: '发票号',
          prop: 'invoiceNo',
        },
        {
          label: '发票数量',
          prop: 'invoiceNum',
        },
      ],
    }
  },
  computed: {
    optionalTableData() {
      return (
        this.tableData?.filter((item) => item.showArea === 'optional') || []
      )
    },
    selectedTableData() {
      return (
        this.tableData?.filter((item) => item.showArea === 'selected') || []
      )
    },
  },
  methods: {
    // 点击上下穿梭逻辑
    transferFn(type) {
      let selectRecords = []
      if (type === 'down') {
        selectRecords = this.$refs.optional.selection
      } else {
        selectRecords = this.$refs.selected.selection
      }
      if (!selectRecords.length) return
      this.tableData.forEach((item) => {
        if (selectRecords.includes(item)) {
          item.showArea = type === 'down' ? 'selected' : 'optional'
        }
      })
    },
  },
}
</script>
<style lang="less" scoped>
.btns {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 10px;
  /deep/.el-button.el-button--primary {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 30px;
    height: 30px;
  }
}
</style>

image.png