CC正在学习中 2022-08-09 19:32 采纳率: 0%
浏览 384
已结题

选项卡加穿梭框的实现

问题遇到的现象和发生背景

初入者,目前项目需要一个选项卡加穿梭框的功能,再一个弹出框里面,左边选项卡要有展开点击功能,点击后获取到index,然后根据index获取到后端数据,渲染到穿梭框左边,穿梭框不能使用按钮,只需要点击一下就可以把左边的数据转移到右边,(左边数据尽量不要消失还是在左边的框里面),右边显示数据后,鼠标移动到数据上要有删除按钮,可以删除掉,左边穿梭框需要一个全选按钮,右边要有一个清空按钮,最后需要将右边的所有值保存下来后需要获取数据,自己利用选项卡和element的transfer组件做了一个,但是重复点击会报错,而且点其他选项卡,会覆盖掉之前的数据。懵逼2天了,实在解决不了,最好使用VUE解决,可以用element组件

大概就是这个样子

img

  • 写回答

14条回答 默认 最新

  • 我啥都会 2022-08-09 21:19
    关注
    获得7.00元问题酬金

    可参考如下穿梭框进行:

    <template>
      <div class="transfer-container">
        <div class="table-transfer">
          <el-row :gutter="24">
            <el-col :span="10" class="left">
              <div class="header">{{titles[0]}}</div>
              <div class="panel">
                <el-input placeholder="请输入内容" v-model="inputContent" clearable @input="handleInputChange" @clear="inputClear"> </el-input>
                <el-table ref="tableRef" :data="currentTableData" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange" @row-click="handleRowClick">
                  <el-table-column type="selection" width="40" :selectable="setSelectable"> </el-table-column>
                  <el-table-column v-for="(item, index) in labelKey" :label="item.label" :prop="item.key" :width="item.width" :key="index" align="center"> </el-table-column>
                </el-table>
              </div>
            </el-col>
            <el-col :span="4" class="buttons">
              <el-button @click="selectChange" ref="selectbtn" :disabled="disabled">选择</el-button>
            </el-col>
            <el-col :span="10" class="right">
              <div class="header">{{titles[1]}}</div>
              <div class="panel">
                <ul>
                  <li class="item" v-for="(item, index) in currentSelection" :key="index">
                    <span>{{ item.name }}</span>
                    <span>{{ item.no }}</span>
                    <i class="el-icon-close" @click="deleteHandle(item)"></i>
                  </li>
                </ul>
              </div>
            </el-col>
          </el-row>
        </div>
      </div>
    </template>
    <script>
    // import specialList from './mock/specialist.json'
     
    export default {
      props: {
        titles: {
          type: Array,
          default: function() {
            return ['', '']
          }
        },
        tableData: {
          type: Array
        },
        selectedData: {
          type: Array
        },
        labelKey: {
          type: Array
        },
        maxSelect: {
          type: Number
        }
      },
      model: {
        prop: 'selectedData',
        event: 'selectChange'
      },
      data() {
        return {
          inputContent: '',
          currentSelection: [],
          currentTableData: [],
          leftSelected: [],
          disabled: true, // 选择按钮默认值
          needSaveCheck: false // 是否需要保存左侧已选择状态
        }
      },
      methods: {
        createMockData() {
          // 随机成成数据
          let data = []
          let zm = ['aa', 'bb', '测试', 'cc', 'n', 'nib', 'speci01', 'p2', 'ccccc', '2021a', '2021b', '2021c', '2021jj', '2021333', 'ccc2021', '231546sss', '3654kkk', 'sssuy']
          for (let i = 0; i < 18; i++) {
            let special = {}
            special.name = zm[i]
            special.no = i + 'i'
            special.finished = Math.round(Math.random() * 100)
            special.unfinished = Math.round(Math.random() * 100)
            data.push(special)
          }
          // console.log(JSON.stringify(data))
        },
        selectChange() {
          // 点击选择按钮
          this.currentSelection = this.currentSelection.concat(this.leftSelected)
          this.currentTableData = this.tableData.filter(item => !this.currentSelection.some(citem => citem.no == item.no))
          this.leftSelected = []
          this.$emit('selectChange', this.currentSelection)
        },
        handleSelectionChange(selection) {
          if (this.needSaveCheck) {
            this.saveSelect()
          } else {
            this.leftSelected = selection
          }
          this.disabled = !(this.leftSelected.length > 0)
        },
     
        handleInputChange() {
          if (this.inputContent == '') {
            this.inputClear()
            return
          }
          const filterData = []
          const leftData = this.tableData.filter(item => !this.currentSelection.some(citem => citem.no == item.no))
          leftData.map(item => {
            if (item.no == this.inputContent || item.name.includes(this.inputContent)) {
              // 根据自己的搜索条件来判断
              filterData.push(item)
            }
          })
          this.currentTableData = filterData
          if (this.leftSelected.length > 0) {
            this.needSaveCheck = true
          }
        },
        inputClear() {
          this.currentTableData = this.tableData.filter(item => !this.currentSelection.some(citem => citem.no == item.no))
          if (this.leftSelected.length > 0) {
            this.needSaveCheck = true
            this.handleSelectionChange()
          }
        },
        setSelectable(row, index) {
          if (this.leftSelected.length + this.currentSelection.length >= this.maxSelect) {
            return this.leftSelected.findIndex(item => item.no == row.no) != -1
          }
          return true
        },
        deleteHandle(special) {
          this.currentSelection.splice(
            this.currentSelection.findIndex(item => item.no === special.no),
            1
          )
          this.currentTableData = this.tableData.filter(item => !this.currentSelection.some(citem => citem.no == item.no))
          this.handleInputChange()
        },
        handleRowClick(row) {
          const allSelectLength = this.leftSelected.length + this.currentSelection.length
          if (allSelectLength == this.maxSelect && this.leftSelected.findIndex(item => item.no === row.no) == -1) {
            return false
          }
          this.$refs.tableRef.toggleRowSelection(row)
        },
        saveSelect() {
          this.$nextTick(() => {
            this.currentTableData.map(item => {
              if (this.leftSelected.findIndex(lef => item.no == lef.no) !== -1) {
                this.$refs.tableRef.toggleRowSelection(item, true)
              }
            })
            this.needSaveCheck = false // 写在nextTick 方法里面很重要
          })
        }
      },
      mounted() {
        this.$nextTick(() => {
          this.currentTableData = this.tableData
        })
      }
    }
    </script>
    <style lang="less" scope>
    div {
      box-sizing: border-box;
    }
    .transfer-container {
      width: 100%;
      padding: 30px;
      text-align: center;
     
      .table-transfer {
        width: 900px;
        min-width: 800px;
        margin: 0 auto;
        .header {
          height: 28px;
          line-height: 28px;
          background-color: cornflowerblue;
          padding-left: 30px;
          color: darkblue;
          text-align: left;
        }
        .panel {
          width: 100%;
          height: 400px;
          border: 1px solid cornflowerblue;
          padding: 10px;
        }
        .buttons {
          line-height: 300px;
        }
        .left {
          .header {
            border-radius: 0px 20px 0 0px;
          }
          .el-input {
            width: 80%;
            margin: 20px 0;
          }
          .el-input__inner {
            height: 30px;
          }
          .el-table__body-wrapper {
            min-height: 200px;
            max-height: 270px;
            overflow: auto;
          }
          .cell {
            padding: 0px;
          }
          td {
            border: none;
          }
          th.is-leaf {
            border: none;
          }
          th {
            .el-checkbox {
              display: none;
            }
          }
          .el-table td {
            padding: 5px 0px;
          }
        }
        .right {
          .header {
            border-radius: 20px 0px 0px 0px;
          }
          ul {
            width: 100%;
            padding-top: 30px;
            li {
              display: flex;
              justify-content: space-between;
              height: 30px;
              line-height: 30px;
            }
            span {
              display: inline-block;
            }
          }
        }
      }
    }
    </style>
    
    data: { 
      // 用下面结构,记得要初始化一下,初始tab数量的空数组出来,要不然你选择tab时不是按顺序来的可能会有问题。
      // chooseData[this.curTabIdx].push(row)
      // 循环的地方记得循环当前索引下的数组
      chooseData: [
        [
          { classesId: 1, classesName: '认可项1', seletedName: '' }
        ],
        [],
        ...
      ],
      // 当前tab索引
      curTabIdx: 0
    }
    
    评论

报告相同问题?

问题事件

  • 系统已结题 8月17日
  • 创建了问题 8月9日

悬赏问题

  • ¥15 vue2(标签-chrome|关键词-浏览器兼容)
  • ¥15 python网络流自动生成系统 医学领域
  • ¥15 sql查询仓库里都有什么
  • ¥15 代码的修改,添加和运行完善
  • ¥15 krpano-场景分组和自定义地图分组
  • ¥15 lammps Gpu加速出错
  • ¥15 关于PLUS模型中kapaa值的问题
  • ¥15 关于博途V17进行仿真时无法建立连接问题
  • ¥15 机器学习教材中的例题询问
  • ¥15 求.net core 几款免费的pdf编辑器