element-ui自制树形穿梭框

发布于:2025-04-04 ⋅ 阅读:(12) ⋅ 点赞:(0)

1、需求

由于业务特殊需求,想要element穿梭框功能,数据是二级树形结构,选中左边数据穿梭到右边后,左边数据不变。多次选中左边相同数据进行穿梭操作,右边数据会多次增加相同的数据。右边数据穿梭回左边时,右边数据会减少,左边数据仍然保持不变。总的来说就是左边数据一直保持不变,右边数据会随着穿梭操作增加或减少,相同数据可以多次添加。(这个需求太特殊了,没办法用组件tree-transfer实现,于是自制了树形穿梭框,记录一下)

2、上代码

 <template>
      <el-dialog title="数据选择" :visible.sync="TransferTreeBoxShow"  width="1500px"  :before-close="handleClose">
        <div class="TransferTreeBox">
          <div class="leftSelect">
             <!-- 左侧待选内容 -->
              <div class="SelectBox">
               <div class="boxTitle">
                 X轴待选 
              </div>
              <div class="boxCenter">
                <el-tree
                ref="beforeTree"
                :data="fromData"
                :props="defaultProps"
                show-checkbox
                :filter-node-method="beforeFilterNode"
                :accordion="true"
                node-key="id"
                />
              </div>
            </div>

            <!-- 中间穿梭按钮 -->
            <div class="transferBtn">
              <div class="pickBtn" @click="towardsRight">
                &gt;&gt;
              </div>
              <div class="pickBtn" @click="towardsLeft">
                &lt;&lt;
              </div>
            </div>

            <!-- 右侧已选内容 -->
            <div class="SelectBox">
              <div class="boxTitle">
                X轴已选
              </div>

              <div class="boxCenter">
                <el-tree
                ref="afterTree"
                :data="fromData2"
                :props="defaultProps"
                show-checkbox
                :filter-node-method="afterFilterNode"
                node-key="id"
                />
              </div>
            </div>

          </div>

  
  </div>
</el-dialog>
  </template>


<script>
export default {
    data () {
        return {
            TransferTreeBoxShow:false,
            defaultProps: {
                children: "children",
                label: "label"
            },
            beforeKeyarr: [],
            afterKeyarr: [],
            fromData2:[],
            fromData: [
            {
                "id": "1",
                "pid": "0",
                "label": "一级",
                "children": [
                    {
                        "id": "1-1",
                        "pid": "1",
                        "label": "1-1级",
                        "children": []
                    },
                    {
                        "id": "1-2",
                        "pid": "1",
                        "label": "1-2级",
                        "children": []
                    },
                    {
                        "id": "1-3",
                        "pid": "1",
                        "label": "1-3级",
                        "children": []
                    },
                    {
                        "id": "1-4",
                        "pid": "1",
                        "label": "1-4级",
                        "children": []
                    },
                    {
                        "id": "1-5",
                        "pid": "1",
                        "label": "1-5级",
                        "children": []
                    }
                  ]
            },
            {
                "id": "2",
                "pid": "0",
                "label": "二级",
                "children": [
                    {
                        "id": "2-1",
                        "pid": "2",
                        "label": "2-1级",
                        "children": []
                    },
                    {
                        "id": "2-2",
                        "pid": "2",
                        "label": "2-2级",
                        "children": []
                    },
                    {
                        "id": "2-3",
                        "pid": "2",
                        "label": "2-3级",
                        "children": []
                    }
                  ]
            },
            {
                "id": "3",
                "pid": "0",
                "label": "三级",
                "children": [
                    {
                        "id": "3-1",
                        "pid": "3",
                        "label": "3-1级",
                        "children": []
                    },
                    {
                        "id": "3-2",
                        "pid": "3",
                        "label": "3-2级",
                        "children": []
                    },
                    {
                        "id": "3-3",
                        "pid": "3",
                        "label": "3-3级",
                        "children": []
                    },
                    {
                        "id": "3-4",
                        "pid": "3",
                        "label": "3-4级",
                        "children": []
                    },
                    {
                        "id": "3-5",
                        "pid": "3",
                        "label": "3-5级",
                        "children": []
                    },
                    {
                        "id": "3-6",
                        "pid": "3",
                        "label": "3-6级",
                        "children": []
                    },
                    {
                        "id": "3-7",
                        "pid": "3",
                        "label": "3-7级",
                        "children": []
                    }
                  ]
            }
          ]
        };
    },
  
    methods: {

      handleClose(done) {
      this.$confirm("确认关闭?")
        .then((_) => {
          done();
        })
        .catch((_) => { });
    },
   
    
        // 点击向右穿梭
        towardsRight(){
            let currentBeforeKeyarr = this.$refs.beforeTree.getCheckedNodes(true);
            for(var i=0;i<currentBeforeKeyarr.length;i++){
                for(var j=0;j<this.fromData.length;j++){
                  var children=this.fromData[j].children;
                  if(children.length>0){
                    if(children.includes(currentBeforeKeyarr[i])){
                      var father=this.fromData[j];
                      var index=-1;
                      for(var k=0;k<this.fromData2.length;k++){
                          if(father.id==this.fromData2[k].id){
                            index=k;
                            break;
                          }
                      }
                      if(index!=-1){
                        var childrenOld=this.fromData2[index].children;
                        var child={id:Math.random(),label:currentBeforeKeyarr[i].label,pid:currentBeforeKeyarr[i].pid,children:[]} 
                        childrenOld.push(child);
                        var newChildren=[];
                        newChildren=newChildren.concat(childrenOld)
                        this.fromData2[index].children=newChildren;
                        
                      }else{
                        var newFather={id:father.id,label:father.label,pid:father.pid,children:[]}    
                        newFather.children.push(currentBeforeKeyarr[i]);
                        this.fromData2.push(newFather);
                      }
                      break;
                    }                   
                  }
                }
            }
            
           
        },
        // 点击向左穿梭
        towardsLeft(){
            this.afterKeyarr = this.$refs.afterTree.getCheckedNodes(true);
            for(var i=0;i<this.afterKeyarr.length;i++){
              for(var j=0;j<this.fromData2.length;j++){
                var children=this.fromData2[j].children;
                for(var k=0;k<children.length;k++){
                
                  if(this.afterKeyarr[i].id==children[k].id){
                    children.splice(k, 1);
                        k--;
                        break;
                  }
                }
                if(children.length==0){
                  this.fromData2.splice(j, 1);
                  j--;
                }
              }
            }

        
        },

       
     
        // 过滤
        beforeFilterNode(value, data) {
            if (!value) {
                return true;
            }

            return value.indexOf(data.id) < 0;
        },
        afterFilterNode(value, data){
            if (!value) {
                return false;
            }

            return value.indexOf(data.value) !== -1;
        },
    }
};
</script>


<style lang="scss" scoped>


.TransferTreeBox  .SelectBox{
        border: 1px solid #ccc;
        height: 100%;
        width: 40%;
        color: #fff;
        position: relative;
}
.TransferTreeBox  .SelectBox        .boxTitle{
            background: #a0cfff;
            height: 30px;
            line-height: 30px;
            text-align: center;
            border-bottom: 1px solid #ccc;
        }

        .TransferTreeBox  .SelectBox       .boxCenter{
            height: 100%;
            width: 100%;
            max-height: 508px;
            overflow-y: scroll;
        }
    

    .TransferTreeBox .transferBtn{
        position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        width: 20%;
    }
    .TransferTreeBox .transferBtn  .pickBtn{
            height: 30px;
            width: 50px;
            background: #a0cfff;
            color: #fff;
            font-weight: 700;
            font-size: 20px;
            border-radius: 5px;
            margin-top: 10px;
            text-align: center;
            line-height: 30px;
            cursor: pointer;
        }
    
/deep/.TransferTreeBox .boxTitle {
    color: #77F7FF;
    background-color: #021F99; /* 深蓝背景 */
}

/deep/.TransferTreeBox .SelectBox .boxTitle {
  color: #77F7FF;
  /* background-color: #021F99; 深蓝背景 */
   background-color: rgba(0, 0, 0, 0); /*透明背景 */
}
/deep/.TransferTreeBox .el-tree-node__content{
  color: #77F7FF;
  background-color: #021F99; /* 深蓝背景 */
}
/deep/.TransferTreeBox .el-tree__empty-block{
  color: #77F7FF;
  background-color: #021F99; /* 深蓝背景 */
}
/deep/.TransferTreeBox .el-tree__empty-text{
  color: #5378F5;
}


.TransferTreeBox {
  height: 600px;
  color: #FFFFFF !important;
  font-size: 20px;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}


/deep/ .el-dialog {
  background: transparent;
  background-image: url("../../assets/boardback.png");
  background-size: cover;
}
/deep/ .el-dialog__title {
  color: #fff;
}
/deep/ .el-dialog__headerbtn .el-dialog__close {
  color: #fff;
}
.rightSelect{
  width: 48%;
  height: 90%;
  display: flex;
  flex-wrap: wrap;
  margin-left:3%;
}
.leftSelect{
  width: 48%;
  height: 90%;
  display: flex;
  flex-wrap: wrap;
}

.TransferTreeBox .Correlation-bottom{
  margin-top:2%;
  width: 100%;
  height: 10%;
  margin-left: 44%;
}

</style>

3、效果图

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/a5bd057007dd4b68847a27c8dac2cfa0.png