基于element-ui的穿梭框(el-transfer)实现点击上下移动

发布于:2022-12-28 ⋅ 阅读:(600) ⋅ 点赞:(0)

实现效果

transfor

<!-- 字段筛选组件 -->
<template>
  <div class="k-field-filter" style="z-index: 99;">
    <div class="field-filter">
      <header>
        <span class="text">设置列表显示字段</span>
        <span class="el-icon-close" @click="closeWindow"></span>
      </header>
      <main class="transfer">
        <el-transfer
                filterable
                filter-placeholder="请输入关键词搜索"
                v-model="value"
                target-order="unshift"
                :titles="['选项合集','已选项合集']"
                :data="data"
                v-loading="loading"
                @right-check-change="choose">
          <el-button
                  class="transer-top ml10"
                  slot="right-footer"
                  size="text"
                  @click="publicMobileMethod('handleUp')"
          ><em class="el-icon-top"></em>
          </el-button>
          <el-button
                  class="transer-top ml10"
                  slot="right-footer"
                  size="text"
                  @click="publicMobileMethod('handleDown')"
          ><em class="el-icon-bottom"></em>
          </el-button>
          <el-button
                  class="transer-top ml10"
                  slot="right-footer"
                  size="text"
                  @click="publicMobileMethod('handleTop')"
          ><em class="iconfont icon-huidaodingbu"></em>
          </el-button>
          <el-button
                  class="transer-top ml10"
                  slot="right-footer"
                  size="text"
                  @click="publicMobileMethod('handleBottom')"
          ><em class="el-icon-download"></em>
          </el-button>
        </el-transfer>
      </main>
      <footer class="footer">
        <div></div>
        <div>
          <el-button class="cancel" size="mini" @click="cancel">取消</el-button>
          <el-button class="determine" size="mini" @click="determine">确定</el-button>
        </div>
      </footer>
    </div>
  </div>
</template>

<script>

export default {
  name: 'KFieldFilter',
  data () {
    return {
      data: [], // 全部数据
      value: [], // 选中数据
      item: [], // 右侧勾选数据
    }
  },
  props: {
    cities: {
      type: Array,
      default: () => [],
    },
    filterSelected: {
      type: Array,
      default: () => [],
    },
    loading: {
      type: Boolean,
      default: false,
    },
  },
  methods: {
    /**
     * 初始数据集
     * @returns {*[]}
     */
    async generateData () {
      const data = []
      this.value = []
      await this.cities.forEach((city) => {
        data.push({
          label: city.field,
          key: city.fieldName,
        })
      })
      this.data = data
      this.value = JSON.parse(JSON.stringify(this.filterSelected))
    },
    /**
     * 关闭弹窗
     */
    closeFilter () {
      this.$emit('closeFilter', false)
    },
    /**
     * 点击x号
     */
    closeWindow () {
      this.cancel()
    },
    /**
     * 确定选择
     */
    determine () {
      this.$emit('determine', this.value)
      this.closeFilter()
    },
    /**
     * 取消选择
     */
    cancel () {
      this.closeFilter()
      this.generateData()
    },
    /**
     * 监听右侧选中
     */
    choose (value) {
      this.item = value
    },
    /**
     * 右侧数据点击排序
     */
    publicMobileMethod (direction) {
      const self = this
      const item = self.item
      let index
      if (item.length === 1) {
        self.value.forEach((val, indexs) => {
          if (val === item[0]) {
            index = indexs
          }
        })
        if (index === 0 && direction !== 'handleBottom' && direction !== 'handleDown') {
          return self.$message('没有上移的空间了')
        }
        if (index === self.value.length - 1 && direction !== 'handleUp' && direction !== 'handleTop') {
          return self.$message('没有下移的空间了')
        }
        // 改变的数组
        const changeItem = self.value[index]
        self.value.splice(index, 1)
        if (direction) {
          // 置顶
          direction === 'handleTop' && self.value.unshift(changeItem)
          // 置底
          direction === 'handleBottom' && self.value.push(changeItem)
          // 上移
          direction === 'handleUp' && self.value.splice(index - 1, 0, changeItem)
          // 下移
          direction === 'handleDown' && self.value.splice(index + 1, 0, changeItem)
        }
      } else if (item.length === 0) {
        self.$message.error('请选择一条数据')
      } else {
        self.$message.error('只能选择一条数据进行上下移动')
      }
    },
  },
  watch: {
    cities: {
      deep: true,
      immediate: true,
      handler () {
        this.generateData()
      },
    },
  },
  mounted () {
    this.generateData()
  },
}
</script>

<style lang='scss' scoped>
.k-field-filter {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, .6);

  .field-filter {
    position: absolute;
    top: 40%;
    left: 50%;
    width: 600px;
    height: 420px;
    overflow-x: auto;
    transform: translate(-50%, -50%);
    background-color: #FFFFFF;
    border: 1px solid rgba(219, 220, 220, 1);
    border-radius: 4px;

    header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: 45px;
      padding: 0 13px;
      border-bottom: 1px solid #DBDCDC;
    }

    .text {
      font-family: "Microsoft YaHei", sans-serif;
      font-size: 14px;
      color: #3C4455;
      line-height: 22px;
      font-weight: 700;
    }

    .el-icon-close {
      cursor: pointer;
      color: #B5B5B5;
    }

    .transfer {
      padding: 13px 13px;
      border-bottom: 1px solid #DBDCDC;
    }

    .footer {
      margin: 8px 8px 0 0;
      display: flex;
      justify-content: space-between;
    }
  }
}
</style>
<style lang="scss">
.field-filter {
  .determine.el-button--mini {
    background-color: #2A76CD;
    color: #FFFFFF;
  }

  .el-transfer__button.cancel,
  .el-button--mini.cancel {
    &:focus,
    &:hover {
      background: #FFFFFF;
      border-color: #2A76CD;
      color: #2A76CD;
    }
  }
}

.el-transfer {
  display: flex;
  justify-content: space-between;
  align-items: center;

  .el-input.el-input--small {
    .el-input__inner {
      border-radius: 4px;
    }
  }

  .el-transfer__buttons {
    padding: 0;
    margin: 0 17px;

    .el-transfer__button {
      display: block;
      margin: 0 0 5px 0;
      padding: 4px 8px;
    }

    .el-button--primary.el-transfer__button {
      display: flex;
      justify-content: center;
      align-items: center;
      background: #2A76CD;
      border-color: #2A76CD;
    }

    .el-button--primary.is-disabled {
      background-color: #a0cfff;
      border-color: #a0cfff;
    }
  }

  .el-checkbox__input.is-indeterminate {
    .el-checkbox__inner {
      background: #2A76CD;
      border-color: #2A76CD;
    }
  }

  .el-transfer-panel {
    width: 49%;
    border-radius: 0;
  }

  .el-transfer-panel__body {
    .el-checkbox__label {
      &:hover {
        color: #2A76CD;
      }
    }
  }

  .el-transfer-panel__header {
    .el-checkbox {
      .el-checkbox__label {
        font-size: 14px;

        span {
          left: 100px
        }
      }
    }
  }

  .el-transfer-panel__footer {
    top: 0;
    left: 61%;
    background-color: transparent;
    display: flex;
    width: 30%;
    justify-content: right;
    border-color: transparent;

    .el-button--text {
      color: #B5B5B5;
      margin-left: 5px;

      .icon-huidaodingbu {
        font-size: 16px;
      }

      em {
        font-size: 14px;
        font-weight: 600;
      }
    }
  }

  .el-transfer-panel:first-child {
    .el-transfer-panel__header {
      .el-checkbox {
        .el-checkbox__label {
          span {
            left: 84px;
          }
        }
      }
    }
  }
}
</style>

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到