左手tree右手transfer的穿梭框

2,066 阅读1分钟

本文是介绍一种实现VUE+ElementUI实现左侧为树形结构、右侧无层级结构的穿梭框的功能。

实现效果

image.png

环境要求

已经安装vue2、element-ui框架的项目

实现思路:左边是未选择列表,使用el-tree树结构的组件,展示了一个二层级的列表,右边是ul>li的无层级列表。当我们选择左边数据时,给选择对象添加父级序列号id(parentIndex),然后push到右边数组keyArr。当我们删除右边数据时,根据parentIndex返回到左边数组和移除右边数组的那一项。

实现代码

<template>
  <div>
    <el-form :model="form" ref="form" label-width="80px" :inline="false">
      <el-form-item label-width="20px">
        <div class="transfer-wrap">
          <div class="left-box">
            <header>未选择列表</header>
            <el-tree @node-click="chooseNode" class="filter-tree" node-key="id" :data="treeList" :props="defaultProps" ref="tree"></el-tree>
          </div>
          <div class="center-icon"><i class="el-icon-arrow-right"></i>&emsp; <i class="el-icon-arrow-left"></i>&emsp;</div>
          <div class="right-box">
            <header>已选择列表</header>
            <div class="right-wrap">
              <ul>
                <li v-for="(item, index) in keyarr" :key="index">
                  <div class="inli">
                    <span>{{ item.label }}</span>
                    <i class="el-icon-close" @click="removeData(index, item)"></i>
                  </div>
                </li>
              </ul>
            </div>
          </div>
        </div>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      form: {
        name: ''
      },
      treeList: [
        {
          id: 1,
          label: '一级 1',
          children: [
            {
              index: 1,
              label: '二级 1-1'
            },
            {
              index: 2,

              label: '二级 1-1'
            },
            {
              index: 3,
              label: '二级 1-1'
            }
          ]
        },
        {
          id: 2,
          label: '一级 2',
          children: [
            {
              index: 4,
              label: '二级 2-1'
            },
            {
              index: 5,
              label: '二级 2-2'
            }
          ]
        },
        {
          id: 3,
          label: '一级 3',
          children: [
            {
              index: 6,
              label: '二级 3-1'
            },
            {
              index: 7,
              label: '二级 3-2'
            }
          ]
        }
      ],
      keyarr: [], //右边数组
      defaultProps: {
        children: 'children',
        label: 'label'
      }
    }
  },
  methods: {
    //左边选择
    chooseNode(obj, node) {
      console.log(obj, node)
      if (obj.index) {
        const indexObj = {}
        console.log(node.parent.parent, '99')
        indexObj.parentIndex = node.parent.parent.data.findIndex(d => d.id === node.parent.data.id) 
        const selfIndex = node.parent.data.children.findIndex(d => d.index === obj.index)
        let newObj = Object.assign(obj, indexObj)
        console.log('newObj', newObj)
        let chooseIndex = this.keyarr.findIndex(i => i.index === newObj.index)
        if (chooseIndex <= -1) {
          this.keyarr.push(newObj)
          node.parent.data.children.splice(selfIndex, 1)
        }
      }
    },
    //右边移除
    removeData(index, data) {
      console.log(index, data)
      if (data.parentIndex >= 0 && this.treeList[data.parentIndex] && this.treeList[data.parentIndex].children) {
        this.keyarr.splice(index, 1)
        let chooseIndex = this.keyarr.findIndex(i => i.index === data.index)
        if (chooseIndex <= -1) {
          this.treeList[data.parentIndex].children.push(data)
        }
      }
    }
  }
}
</script>

<style scoped>
.transfer-wrap {
  display: flex;
}
.center-icon {
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin-left: 7px;
  margin-right: 7px;
}

.el-tree {
  width: 176px;
  height: 232px;
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  overflow: auto;
}
i {
  padding: 6px;
  margin-top: 4px;
  background-color: #f4f4f4;
  border: 1px solid #d1d1d1;
  box-sizing: border-box;
}
.right-wrap {
  width: 176px;
  height: 232px;
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  overflow: auto;
}
li {
  list-style: none;
}
</style>