美文网首页
Transfer封装

Transfer封装

作者: 累累的 | 来源:发表于2022-08-18 17:57 被阅读0次

近期项目中遇到穿梭框功能,将其过程做以总结:

效果图

效果预览

思路

  1. 获取左侧勾选的值(checkedList)
  2. 将checkedList循环一遍push进右侧(rightList)
  3. 把leftList和rightList做一遍过滤遍历 使用filtersome函数来过滤去重 这样是为了避免已经添加到右侧之后左侧还有对应的城市

代码

item.vue

<template>
<el-card class="item">
  <div class="header">
    <el-row :gutter="16">
      <!-- <el-col span="12"> <el-select></el-select></el-col>
        <el-col span="12"> <el-select></el-select></el-col>
        <el-col span="12"> <el-select></el-select></el-col>
        <el-col span="12"> <el-input placeholder="单位名称"></el-input></el-col> -->
  </el-row>
  </div>
  <div class="checkAll">
    <el-checkbox
                 :isIndeterminate="isIndeterminate"
                 v-model="checkAll"
                 @change="handleCheckAllChange"
                 >全选</el-checkbox
      >
    <span>{{ checkedCompanies.length }}/{{ checkList.length }}</span>
  </div>
  <div class="checkbox">
    <el-checkbox-group
                       v-model="checkedCompanies"
                       @change="handleCheckedCitiesChange"
                       >
      <el-checkbox
                   class="checkItem"
                   v-for="item in checkList"
                   :label="JSON.stringify(item)"
                   :key="item.companyId"
                   >{{ item.companyName }}</el-checkbox
        >
  </el-checkbox-group>
  </div>
  </el-card>
</template>
<script>
  export default {
    name: 'TransferItem',
    components: {},
    props: {
      checkList: {
        type: Array,
        default: () => []
      }
    },
    data() {
      return {
        checkedCompanies: [],
        checkAll: false,
        isIndeterminate: true
      }
    },
    computed: {},
    methods: {
      // 全选
      handleCheckAllChange(val) {
        // 因为后端需要id和name 所以label绑定的是把item转成对象
        const arr = this.checkList.map((item) => JSON.stringify(item))
        this.checkedCompanies = val ? arr : []
        this.isIndeterminate = false
        this.$emit('change', this.checkList)
      },
      // 单选
      handleCheckedCitiesChange(value) {
        let checkedCount = value.length
        this.checkAll = checkedCount === this.checkList.length
        this.isIndeterminate =
          checkedCount > 0 && checkedCount < this.checkList.length
        const arr = value.map((item) => JSON.parse(item))
        this.$emit('change', arr)
      },
      // 清除勾选状态
      clearCheck() {
        this.checkedCompanies = []
        this.checkAll = false
        this.isIndeterminate = true
      }
    },
    created() {},
    mounted() {}
  }
</script>
<style lang="scss" scoped>
  .item {
    width: 340px;
    height: 330px;
    .header {
      padding: 0 12px;
      padding-top: 8px;
      .el-col {
        margin-bottom: 8px;
      }
    }
    .checkAll {
      background: #f7f8fa;
      color: #7d8292;
      font-size: 12px;
      height: 40px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 12px;
    }
    .checkbox {
      height: 200px;
      overflow: auto;
      /deep/ .el-checkbox-group {
        display: flex;
        flex-direction: column;
        .checkItem {
          margin-right: 0px;
          height: 40px;
          padding: 0 12px;
          color: #424656;
          font-size: 12px;
          line-height: 40px;
          border-bottom: 1px solid #f2f2f2;
        }
      }
    }
  }
</style>

header里面可以放需要的查询条件

Transfer.vue

<template>
  <div class="Transfer">
    <div class="left">
      <Item ref="left" :checkList="leftList" @change="leftChange" />
    </div>
    <div class="btn">
      <el-button type="primary" style="margin-bottom: 60px" @click="add()"
        >&gt;添加</el-button
      >
      <el-button style="margin: 0" @click="remove()">&lt;删除</el-button>
    </div>
    <div class="right">
      <Item ref="right" :checkList="rightList" @change="rightChange" />
    </div>
  </div>
</template>
<script>
import Item from './components/Item.vue'
import { deepClone, filterData } from '@/utils/index'
export default {
  name: 'Transfer',
  components: { Item },
  props: {
    checkLeftList: {
      type: Array,
      default: () => []
    },
    checkRightList: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      // 左边列表
      leftList: [],
      // 左边选中
      leftChecked: [],
      rightList: [],
      rightChecked: []
    }
  },
  watch: {
    checkLeftList: {
      handler(v) {
        if (v) {
          this.leftList = deepClone(v)
        }
      },
      deep: true,
      immediate: true
    },
    checkRightList: {
      handler(v) {
        if (v) {
          this.rightList = deepClone(v)
        }
      },
      deep: true,
      immediate: true
    }
  },
  computed: {},
  methods: {
    leftChange(checked) {
      this.leftChecked = checked
    },
    rightChange(checked) {
      this.rightChecked = checked
    },
    // 添加
    add() {
      // 把左侧勾选的值添加到右侧
      this.leftChecked.forEach((v) => {
        if (v) this.rightList.push(v)
      })
      // 拿左侧的值和右侧的值做一遍过滤遍历
      this.leftList = filterData(
        this.leftList,
        this.rightList,
        'companyId',
        'companyId'
      )
      this.$refs.left.clearCheck()
    },
    remove() {
      this.rightChecked.forEach((v) => {
        if (v) this.leftList.push(v)
      })
      this.rightList = filterData(
        this.rightList,
        this.leftList,
        'companyId',
        'companyId'
      )
      this.$refs.right.clearCheck()
    }
  },
  created() {},
  mounted() {}
}
</script>
<style lang="scss" scoped>
.Transfer {
  display: flex;
  .left,
  .right {
    border: 1px solid #eaecf1;
  }
  .btn {
    width: 100px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
}
</style>

过滤函数

// 2个数组过滤重复数据
/**
*
* @param {Array} arr1 数组1
* @param {Array} arr2 数组2
* @param {String||Number} arr1key 数组1的key
* @param {String||Number} arr2key 数组2的key
* @returns Array
*/
export function filterData(arr1, arr2, arr1key, arr2key) {
  return arr1.filter(
    (item) => !arr2.some((ele) => ele[arr2key] === item[arr1key])
  )
}

相关文章

网友评论

      本文标题:Transfer封装

      本文链接:https://www.haomeiwen.com/subject/pnmugrtx.html