el-Transfer 穿梭框重写左右拖拽及排序组件

1.适用组件:

导入,注册组件,然后使用

<DragTransfer
            v-model="rightData"
            leftTitle="未选择字段"
            rightTitle="已选择字段"
            :props="transferProps"
            :data="data"
          ></DragTransfer>

 

参数解释:
v-model="rightData"  右边已选择的数据
 :data="data" 所有数据,左边和右边一起的数据
leftTitle="未选择字段"  左边标题
 rightTitle="已选择字段" 右边标题
:props="transferProps" 字段映射

 

 
vue  data中定义:
transferProps: {
        value: "rfidSetId",
        label: "rfidSetName",
      },

 

2.左右拖拽组件:

src/components/DragTransfer.vue

复制代码
<template>
  <div class="drag-transfer">
    <div class="drag-transfer-content">
      <div class="drag-transfer-left">
        <div class="drag-transfer-title">{{ leftTitle }}</div>
        <div
          id="left"
          class="drag-transfer-item"
          @drop="drop"
          @dragover="allowDrop"
        >
          <template v-for="(item, index) in leftData">
            <div
              :key="index"
              class="drag-transfer-item-name"
              draggable="true"
              @dragstart="dragstart"
              :id="item[props['value']]"
            >
              {{ item[props["label"]] }}
            </div>
          </template>
        </div>
      </div>

      <div class="drag-transfer-right">
        <div class="drag-transfer-title">{{ rightTitle }}</div>
        <div
          id="right"
          class="drag-transfer-item"
          @drop="drop"
          @dragover="allowDrop"
        >
          <template v-for="(item, index) in rightData">
            <div
              :key="index"
              class="drag-transfer-item-name"
              draggable="true"
              @dragstart="dragstart"
              :id="item[props['value']]"
            >
              {{ item[props["label"]] }}
            </div>
          </template>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "drag-transfer",
  model: {
    prop: "rightData",
    event: "chageRightData",
  },
  props: {
    rightData: {
      type: Array,
      default: () => [],
    },
    leftTitle: {
      type: String,
      default: "未选择",
    },
    rightTitle: {
      type: String,
      default: "已选择",
    },
    props: {
      type: Object,
      default: () => ({
        value: "value",
        label: "label",
      }),
    },
    data: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      leftData: [],
      tableData: [],
    };
  },
  mounted() {},
  watch: {
    data: {
      handler(val) {
        const self = this;
        this.leftData = [];
        this.data.forEach(function (element) {
          const index = self.rightData.findIndex(
            (x) => x[self.props["value"]] == element[self.props["value"]]
          );
          if (index == -1) {
            self.leftData.push(element);
          }
        });
      },
      deep: true,
    },
  },
  methods: {
    switchLeftNumber(sourceObj, targetObj) {
      const self = this;
      const sourceIndex = this.getLeftIndex(sourceObj[self.props["value"]]);
      const targetIndex = this.getLeftIndex(targetObj[self.props["value"]]);

      let arr = JSON.parse(JSON.stringify(this.leftData));
      arr[sourceIndex] = targetObj;
      arr[targetIndex] = sourceObj;
      this.leftData = arr;
    },
    switchRightNumber(sourceObj, targetObj) {
      const self = this;
      const sourceIndex = this.getRightIndex(sourceObj[self.props["value"]]);
      const targetIndex = this.getRightIndex(targetObj[self.props["value"]]);

      let arr = JSON.parse(JSON.stringify(this.rightData));
      arr[sourceIndex] = targetObj;
      arr[targetIndex] = sourceObj;
      this.rightData = arr;

      // for (const element of this.rightData) {
      //   if (element[self.props["value"]] == sourceObj[self.props["value"]]) {
      //     console.log("targetObj", element, targetObj);
      //     // element = targetObj;
      //   }
      //   if (element[self.props["value"]] == targetObj[self.props["value"]]) {
      //     console.log("sourceObj", element, sourceObj);
      //     // element = sourceObj;
      //   }
      // }
    },
    dragRightToLeft(sourceData, tagetId) {
      sourceData.status = false;
      if (tagetId & (tagetId != "left")) {
        //放到元素上,在此处插入
        const targetIndex = this.leftData.findIndex(
          (x) => x[this.props["value"]] == tagetId
        );
        this.leftData.splice(targetIndex, 0, sourceData);
      } else {
        //未放到元素上,追加尾部
        this.leftData.push(sourceData);
      }
      this.rightData = this.rightData.filter(
        (x) => x[this.props["value"]] != sourceData[this.props["value"]]
      );
    },
    dragLeftToRight(sourceData, tagetId) {
      sourceData.status = true;
      if (tagetId && tagetId != "right") {
        //放到元素上,在此处插入
        const targetIndex = this.rightData.findIndex(
          (x) => x[this.props["value"]] == tagetId
        );
        this.rightData.splice(targetIndex, 0, sourceData);
      } else {
        //未放到元素上,追加尾部
        this.rightData.push(sourceData);
      }
      this.leftData = this.leftData.filter(
        (x) => x[this.props["value"]] != sourceData[this.props["value"]]
      );
    },
    getDataById(id) {
      const dataList = this.data.filter((x) => x[this.props["value"]] == id);
      return dataList ? dataList[0] : {};
    },
    getRightDataById(id) {
      const dataList = this.rightData.filter(
        (x) => x[this.props["value"]] == id
      );
      return dataList ? dataList[0] : {};
    },
    getLeftIndex(id) {
      return this.leftData.findIndex((x) => x[this.props["value"]] == id);
    },
    getRightIndex(id) {
      return this.rightData.findIndex((x) => x[this.props["value"]] == id);
    },
    getLeftDataById(id) {
      const dataList = this.leftData.filter(
        (x) => x[this.props["value"]] == id
      );
      return dataList ? dataList[0] : {};
    },
    allowDrop(ev) {
      ev.preventDefault();
    },
    dragstart(ev) {
      ev.dataTransfer.setData("id", ev.target.id);
    },
    drop(ev) {
      ev.preventDefault();
      debugger;
      const source_id = ev.dataTransfer.getData("id");
      const target_id = ev.target.id;
      if (source_id && target_id) {
        const left_source_obj = this.getLeftDataById(source_id);
        const left_target_obj = this.getLeftDataById(target_id);
        const right_source_obj = this.getRightDataById(source_id);
        const right_target_obj = this.getRightDataById(target_id);
        if (left_source_obj && (right_target_obj || target_id == "right")) {
          //左边-右边
          this.dragLeftToRight(left_source_obj, target_id);
        } else if (
          right_source_obj &&
          (left_target_obj || target_id == "left")
        ) {
          //右边-左边
          this.dragRightToLeft(right_source_obj, target_id);
        } else if (
          left_source_obj &&
          (left_target_obj || target_id == "left")
        ) {
          //左边调换顺序
          //this.switchLeftNumber(left_source_obj, left_target_obj);
        } else if (
          right_source_obj &&
          (right_target_obj || target_id == "right")
        ) {
          if (target_id == "right") {
            this.rightData = this.rightData.filter(
              (x) =>
                x[this.props["value"]] != right_source_obj[this.props["value"]]
            );
            this.rightData.push(right_source_obj);
          } else {
            //右边调换顺序
            this.switchRightNumber(right_source_obj, right_target_obj);
          }
        }
      }
      this.$emit("chageRightData", this.rightData);
    },
  },
};
</script>
<style scoped>
.drag-transfer {
  margin: 0;
  padding: 0;
  height: 450px;
}
.drag-transfer-title {
  position: relative;
  top: -13px;
  left: 73px;
}
.drag-transfer-content {
}
.drag-transfer-item {
  width: 260px;
  height: 100%;
  border: 1px dashed #b2a8a8;
  overflow-y: auto;
  overflow-x: hidden;
}
.drag-transfer-left {
  float: left;
  height: 400px;
}
.drag-transfer-right {
  float: left;
  margin-left: 116px;
  height: 400px;
}
.drag-transfer-item-name {
  /* width: 84px;
  height: 20px;
  font-size: 14px;
  font-family: PingFangSC-Medium, PingFang SC;
  font-weight: 500;
  color: #4a4a4a;
  line-height: 20px;

width: 200px;
height: 36px;
background: #42E8DF;
border-radius: 4px; */

  padding: 10px;
  text-align: center;
  width: 200px;
  height: 36px;
  background: #42e8df;
  border-radius: 4px;
  margin: 10px 30px;
  color: #4a4a4a;
}
</style>
复制代码
posted @   土豆哥  阅读(2352)  评论(0编辑  收藏  举报
编辑推荐:
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
阅读排行:
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee
· 用 DeepSeek 给对象做个网站,她一定感动坏了
· .NET 8.0 + Linux 香橙派,实现高效的 IoT 数据采集与控制解决方案
· DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件
点击右上角即可分享
微信分享提示