likes
comments
collection
share

vue3基于element-plus开发树形穿梭框

作者站长头像
站长
· 阅读数 39

临时搞出来的,还没仔细测过,有时间再优化优化先上效果图vue3基于element-plus开发树形穿梭框index.vue

<template>
  <div>
    <tree-transfer
      ref="treeTransferRef"
      :nodeKey="'id'"
      :fromData="fromData"
      :toData="toData"
      :defaultProps="transferProps" 
      :leftTit="'左侧标题'"
      :rightTit="'右侧标题'"
      @checkVal="checkVal"/>
  </div>
</template>
<script setup>
import treeTransfer from '@/components/tree-transfer.vue'
import { ref } from 'vue'
  let treeTransferRef = ref();//树形穿梭框

  let fromData = ref([]);//树形数据
  let toData = ref([]);//选中的ids数据
  const transferProps = ref({
    label:'name',
    children:'children',
    disabled:'disabled',
  })

  //方法

  //子组件树形穿梭框返回
  const checkVal =(val)=>{
    let arr = []
    for(var i in val){
       arr.push(val[i].id)
    }
    toData.value = arr
  }
</script>
<style lang='scss'>

</style>

tree-transfer.vue

<template>
  <div class='treeTransfer'>
    <div class="leftTree">
      <div class="treeTit">{{props.leftTit||'左侧栏'}}</div>
      <div class="list">
        <el-tree
          ref="treeRef"
          :data="props.fromData"
          show-checkbox
          default-expand-all
          :node-key="props.nodeKey"
          highlight-current
          :props="props.defaultProps"
          :default-checked-keys="props.toData"
        />
      </div>
    </div>
    <div class="btnDiv">
      <div class="mg10" @click="toRight()"><el-button :icon="Right" circle /></div>
      <div class="mg10" @click="toLeft()"><el-button :icon="Back" circle /></div>
    </div>
    <div class="rightTree">
      <div class="treeTit">{{props.rightTit||'右侧栏'}}</div>
      <div class="list">
        <div :class="['item',{'active':item.active}]" v-for="(item,index) in toData" :key="index" @click="checkNode(item)">{{item[props.defaultProps.label]}}</div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { ref,reactive,onMounted, nextTick } from 'vue'
import { Right,Back } from '@element-plus/icons-vue';
const props = defineProps(['nodeKey','fromData','toData','defaultProps','leftTit','rightTit'])
//定义emit
const emit = defineEmits(['checkVal'])
  const treeRef = ref()

  //右侧数据
  const toData = ref([]);

  onMounted(()=>{
    if(props.toData.length>0){
      toData.value = treeRef.value.getCheckedNodes(false, false)
      treeRef.value.setCheckedKeys([], false)
    }
  })

  //方法
  //去右边
  const toRight = () =>{
    const checkNodes = treeRef.value.getCheckedNodes(false, false)
    const newArr = toData.value.concat(checkNodes)
    let obj = {};
    let peon = newArr.reduce((cur,next) => {
        obj[next[props.nodeKey]] ? "" : obj[next[props.nodeKey]] = true && cur.push(next);
        return cur;
    },[]) //设置cur默认类型为数组,并且初始值为空的数组
    toData.value = peon
    treeRef.value.setCheckedKeys([], false)
    checkVal()
  }
  //去左边
  const toLeft = () =>{
    for(var i=0; i<toData.value.length;i++){
      if(toData.value[i].active){
        toData.value[i].active = false
        toData.value.splice(i,1)
        i-=1
      }
    }
    checkVal()
  }
  //右侧item点击
  const checkNode = (item) =>{
    item.active = !item.active
  }
  //返回父组件
  const checkVal = () =>{
    emit('checkVal',toData.value)
  }

</script>
<style lang='scss'>
.treeTransfer{
  display: flex;
  justify-content: space-between;
  .mg10{
    margin:10px;
  }
  .leftTree,.rightTree{
    flex-grow: 1;
    width: calc((100% - 60px) / 2);
    .treeTit{
      margin-bottom: 10px;
    }
    .list{
      overflow: auto;
      height: 300px;
      border: 1px solid #ddd;
      border-radius: 4px;
      .item{
        padding: 3px 10px;
        cursor: pointer;
        margin-bottom: 1px;
        &.active{
          background: #b9d7fa;
        }
      }
    }
  }
  .btnDiv{
    width: 60px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}
</style>
转载自:https://segmentfault.com/a/1190000043047925
评论
请登录