欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

element-ui实现一个穿梭框

程序员文章站 2022-06-19 16:57:41
...

这篇文章将长期更新。
先陈述下,目前的找到的一些穿梭框:
1.element-ui中的穿梭框,功能单一,不能满足需求;
2.其它的ui框架大部分也是功能单一;
3.npm中有一个插件,el-tree-transfer,封装了大部分功能,且待完善的功能也有提供,可自行改动。

前人已经有些好,之所以自己还要重新去构建的原因是因为,单一的一个功能,且穿梭框的实现并不复杂,引入一个插件且在功能实现上也引用了element-ui的组件去改造的(不是引用穿梭框组件,而是其他的组件拼起来),且还需要改成自己的设计风格,时间和成本上都得不偿失。

所以,既然都是依托在element-ui上,功能也不复杂,还不如自己用element-ui实现一个穿梭框;

设计的初衷在于方便使用,将每种的穿梭框做出组件的形式,且提供源码进行改造;为了节省精力,不会进行封装;(日常加班,主要是没时间没精力(;′⌒`)

功能涵括多种穿梭框:(皆由element-ui组件拼凑修改)
1.搜索功能:
1.1 下拉搜索;
1.2 输入搜索
2.树形到多选框;
3.多选到树形框;
4.树形框到树形框;

目前已经实现下拉功能,写的有点急,样式很丑,可能还有写bug,写的过程中修复了一些(;′⌒`),后续将慢慢进行完善。
代码先暂存下,后续的代码也都将上传到github上
第一更新:2019.10.20

<template>
  <!-- 将全选改成下拉框思路:

  form表单中的下拉框:
    1.拿到所选择的下拉内容的title,
    2.再根据title的其他属性,
    3.拿到title对应的数据,
    4.用这个数据,将原本的leftlists替换掉
    5.改进,用方法change去进行监听,并将方法加载再created中, 目的是为了将页面加载后,显示下来中的某一内容为初始值; -->
  <div class="transfer-box">
    <!-- 左边 -->
    <div class="left">
      <div class="left-header">
        <el-checkbox
          :indeterminate="leftIndeterminate"
          v-model="leftAll"
          @change="handleLeftAllChange"
        ></el-checkbox>
        <el-select v-model="region" clearable filterable placeholder="请选择活动区域">
          <el-option label="区域一" value="1"></el-option>
          <el-option label="区域二" value="2"></el-option>
        </el-select>
        <!-- 左边--下拉框 -->
      </div>
      <!-- 左边--显示内容 -->
      <el-checkbox-group
        class="left-content"
        v-model="checkedLeft"
        @change="handleCheckedLeftChange"
      >
        <el-checkbox
          v-for="(data,index) in leftLists"
          :label="data"
          :key="index"
        >{{index+'----------'+data}}</el-checkbox>
      </el-checkbox-group>
    </div>

    <!-- 中间移动按钮 -->
    <div class="middle-btn">
      <el-button
        class="right-to-left"
        @click="RightToLeft()"
        size="small"
        icon="el-icon-arrow-left"
      ></el-button>
      <el-button @click="leftToRight()" size="small" icon="el-icon-arrow-right"></el-button>
    </div>

    <!-- 右边 -->
    <div class="right">
      <div class="right-header">
        <el-checkbox
          :indeterminate="rightIndeterminate"
          v-model="rightAll"
          @change="handleRightAllChange"
        >全选</el-checkbox>

        <!-- 右边--下拉框 -->
      </div>

      <!-- 右边内容 -->
      <el-checkbox-group
        class="right-content"
        v-model="checkedRight"
        @change="handleCheckedRightChange"
      >
        <el-checkbox
          v-for="(item,index) in rightLists"
          :label="item"
          :key="index"
        >{{index+'----------'+item}}</el-checkbox>
      </el-checkbox-group>
    </div>
  </div>
</template>
<script>
const data = ["aa", "bb", "cc", "dd", "ee", "ff"];
const data2 = ["aaa", "bbaa", "ccss", "ddddd", "fffee", "fffff"];
export default {
  data() {
    return {
      leftAll: false,
      rightAll: false, //全选显示'√',部分则显示'-'
      checkedLeft: [],
      checkedRight: [],
      leftLists: ["深圳", "上海", "广州", "北京", "厦门", "珠海"],
      rightLists: ["sz", "sh", "gz", "bj", "xm", "zh"],
      leftIndeterminate: false,
      rightIndeterminate: false, //控制显示空白还是蓝色
      region: ""
    };
  },
  watch: {
    // leftIndeterminate() {
    //   console.info("r-indete", this.leftIndeterminate);
    // },
    // leftAll() {
    //   console.info("r-all", this.leftAll);
    // },
    // checkedLeft() {
    //   console.info("checkedLeft", this.checkedLeft);
    // },
    // checkedRight() {
    //   console.info("checkedRight", this.checkedRight);
    // }
    region() {
      console.log(this.region);
      if (this.region === "1") {
        this.leftLists = data;
        console.log(this.leftLists)
      }
      if (this.region === "2") {
        this.leftLists = data2;
      }
    }
  },
  methods: {
    handleLeftAllChange(val) {
      this.checkedLeft = val ? this.leftLists : [];
      this.leftIndeterminate = false;
    },
    handleCheckedLeftChange(value) {
      let checkedLeftCount = value.length;
      this.leftAll = checkedLeftCount === this.leftLists.length;
      this.leftIndeterminate =
        checkedLeftCount > 0 && checkedLeftCount < this.leftLists.length;
    },
    handleRightAllChange(val) {
      // debugger
      this.checkedRight = val ? this.rightLists : [];
      this.rightIndeterminate = false;
    },
    handleCheckedRightChange(value) {
      let checkedRightCount = value.length;
      this.rightAll = checkedRightCount === this.rightLists.length;
      this.rightIndeterminate =
        checkedRightCount > 0 && checkedRightCount < this.rightLists.length;
    },
    leftToRight() {
      if (this.checkedLeft.length !== 0) {
        // let msg = this.checkedLeft;
        // console.info(msg);
        this.rightLists.push(...this.checkedLeft);
        this.leftLists = this.unique(this.leftLists, this.checkedLeft);
        this.checkedLeft = [];
        this.leftIndeterminate = false;
        this.leftAll = false;

        // console.info("右边的数据", this.rightLists);
        // console.info("左边更新后的数据", this.leftLists);
      } else {
        // 增加一个弹框,提示选择
      }
    },
    RightToLeft() {
      if (this.checkedRight.length !== 0) {
        // let msg1 = this.checkedRight;
        this.leftLists.push(...this.checkedRight);
        // console.log(this.leftLists);
        this.rightLists = this.unique(this.rightLists, this.checkedRight);
        this.checkedRight = [];
        this.rightIndeterminate = false;
        this.rightAll = false;
        // console.log(this.rightLists);
        // // console.info("右边的数据", this.leftLists);
      }
    },
    // 添加一个去掉原来的项的方法,并且重置全选状态
    unique(a, b) {
      for (var i = 0; i < b.length; i++) {
        for (var j = 0; j < a.length; j++) {
          if (a[j] == b[i]) {
            a.splice(j, 1);
            j = j - 1;
          }
        }
      }
      return a;
      // fatherArray.forEach(function(data, i) {
      //   sonArray.forEach(function(items) {
      //     if (data === items) {
      //       fatherArray.splice(i, 1);
      //     }
      //   });
      // });
    }
  }
};
</script>

<style lang="scss" scoped>
.el-button {
  margin: 0;
}
.transfer-box {
  display: flex;
  justify-content: space-between;
}
.left {
  display: flex;
  width: 500px;
  height: 500px;
  border: 1px solid #ccc;
  flex-direction: column;
}
.left-header,
.right-header {
  background-color: #ddd;
  text-align: left;
  padding: 10px 0;
  padding-left: 32px;
}
.left-content {
  display: flex;
  flex-direction: column;
  text-align: left;
  margin-left: 50px;
  margin-top: 20px;
}
.left-content .el-checkbox {
  padding: 10px;
  font-size: 16px;
}
.middle-btn {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.right-to-left {
  margin-bottom: 50px;
}

.right {
  display: flex;
  width: 500px;
  height: 500px;
  border: 1px solid #ccc;
  flex-direction: column;
}
.right-content {
  display: flex;
  flex-direction: column;
  text-align: left;
  margin-left: 50px;
  margin-top: 20px;
}
.right-content .el-checkbox {
  padding: 10px;
  font-size: 16px;
}
</style>
相关标签: vue transfer