基于element-ui的穿梭框(el-transfer)实现点击上下移动(按钮写入每行)

这篇具有很好参考价值的文章主要介绍了基于element-ui的穿梭框(el-transfer)实现点击上下移动(按钮写入每行)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

transfer(行内)文章来源地址https://www.toymoban.com/news/detail-555061.html

<!-- 字段筛选组件 -->
<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">
          <div slot-scope="{ option }">
            <div class="default-tranfer-item" @mouseenter="indexKey = option.key"
                 @mouseleave="indexKey = null">
              <span>{{ option.label }}</span>
              <div v-show="value.includes(option.key) && indexKey === option.key" class="button-group">
                <!--  阻止事件冒泡  -->
                <!-- 自定义数据项,将上、下、底部、顶部的排序功能放在数据项里面 -->
                <em class="el-icon-top" @click.stop.prevent="publicMobileMethod('handleUp', option.key)"></em>
                <em class="iconfont icon-huidaodingbu"
                    @click.stop.prevent="publicMobileMethod('handleTop', option.key)"></em>
                <em class="el-icon-bottom" @click.stop.prevent="publicMobileMethod('handleDown', option.key)"></em>
                <em class="el-icon-download" @click.stop.prevent="publicMobileMethod('handleBottom', option.key)"></em>
              </div>
            </div>
          </div>
        </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',
  /**
   * 初始化数据
   * @returns {{item: *[], data: *[], indexKey: null, value: *[]}}
   */
  data () {
    return {
      data: [], // 全部数据
      value: [], // 选中数据
      item: [], // 右侧勾选数据
      indexKey: null, // 高亮显示
    }
  },
  props: {
    cities: {
      type: Array,
      /**
       * 全部数据
       * @returns {*[]}
       */
      default: () => [],
    },
    filterSelected: {
      type: Array,
      /**
       * 右侧数据
       * @returns {*[]}
       */
      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, key) {
      const self = this
      let index
      // 判断是否超出一条
      const item = self.item
      if (item.length === 1 || item.length === 0) {
        self.value.forEach((val, indexs) => {
          // 获取需移动数据的下标
          if (val === key) {
            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 {
        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-transfer-panel__item {
      margin-right: 0;
    }

    .default-tranfer-item {
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .button-group {
        em {
          margin-right: 8px;
        }
      }
    }

    .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>

到了这里,关于基于element-ui的穿梭框(el-transfer)实现点击上下移动(按钮写入每行)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue + element-ui 穿梭框+上下移动、置顶置底功能

    预览效果:  代码 :

    2024年02月11日
    浏览(53)
  • 基于element-ui el-slider实现滑动限位器

    应需求需要,要做一个滑动限位器,一通百度,一通谷歌,没有相对应的解决方案,所以只能自己上。过程有丢丢曲折,比较细的东西。所以耗时也长写。写出来有需要的可以参考 需求图如下: 上面的滑块是可以在区间【50-100】之间随意切换的。左边和右边也是可以随意拉

    2024年02月15日
    浏览(54)
  • 基于element-ui el-dialog组件封装,可缩放+可移动的弹窗组件

    源码下载 改组件继承el-dialog组件百分之95属性,可直接对el-dialog进行替换。在项目中我的命名为: vue代码 :搞成组件,路径随意,推荐统一放在组件目录下 拖动及缩放操作js代码: 将skdialog.js注册为指令: 目录: 指令使用:(v-指令名称(SkDialogDrag)) 效果图: 注:吃水

    2024年02月03日
    浏览(58)
  • element-ui文件上传el-upload

            element-ui官网中有文件上传         首先先展示一下我页面的实现效果,如下图所示:          从图中可以看出,我这边实现的是一个可显示进度条的文件上传操作,而且如果上传的文件很大等,还可以中断文件上传。         值得注意的是,如果有添

    2024年02月05日
    浏览(51)
  • 【element-ui】el-dialog改变宽度

    dialog默认宽度为父元素的50%,这就导致在移动端会非常的窄,如图1,需要限定宽度。 解决方法:添加 custom-class 属性,然后在style中编写样式, 注意 ,如果有 scoped 限定,需要加 ::v-deep

    2024年02月11日
    浏览(55)
  • element-ui树形控件el-tree详解

    概述 这里我利用element-ui开发一个vue的树形组件 引入element-ui 安装element-plus 安装按需导入 修改vite.config.js配置按需加载 tree树形控件详解 属性名 说明 类型 可选值 默认值 data 展示数据 array — — empty-text 内容为空的时候展示的文本 string — — node-key 每个树节点用来作为唯一标

    2024年02月07日
    浏览(105)
  • [element-ui] el-tree 懒加载load

    懒加载:点击节点时才进行该层数据的获取。 注意:使用了懒加载之后,一般情况下就可以不用绑定:data。 懒加载—由于在点击节点时才进行该层数据的获取,默认情况下 Tree 无法预知某个节点是否为叶子节点,所以会为每个节点添加一个下拉按钮,如果节点没有下层数据,

    2024年02月11日
    浏览(62)
  • [element-ui] el-tree全部展开与收回

    参考: el-tree全部展开与收回

    2024年02月10日
    浏览(48)
  • element-ui的el-dialog,简单的封装。

    el-dialog是使用率很高的组件 使用el-dialog很多都是按照文档的例子,用一个变量控制是否显示,再来一个变量控制标题。 如果我这个对话框多个地方使用的话还要创建多个变量,甚至关闭之后还要清空一些变量,应该可以简化一点。我写vue的时候奉行的都是数据驱动,像刚才

    2024年02月12日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包