根据el-table封装一个穿梭框。

378 阅读1分钟

在element-ui中有穿梭框,但是el-transfer不能满足一些特定的需求,比如多部门人员之间的调动,所以我们需要手动封装一下zb-transfer。 父组件

  <template>
       <div class="transfer">
           <zb-transfer
            ref="transfer" 
            v-model="value"
            :allNumber="allNumber"
            :leftDataRemain="leftData"
            :columns="columns" 
            :keyName="keyName"
            @change="change"
            ></zb-transfer>
       </div>
</template>
<script>
 export default {
    data() {
       return {
          keyName: 'userId',  //keyName根据你的数据的唯一值进行穿梭,我这里传的是userId,你可以传别的
          value: [],
          columns: [
           {
             key: 'name',
             label: '名字',
             visible: true
           }
          ],
          //全部部门的数据
          allNumber: [
            {
              name: '张三',
              userId: 1
            },{
              name: '李四',
              userId: 2
            },{
              name: '王五',
              userId: 3
            },{
              name: '刘能',
              userId: 4
            },{
              name: '张三1',
              userId: 5
            },{
              name: '李四1',
              userId: 6
            },{
              name: '王五1',
              userId: 7
            },{
              name: '刘能1',
              userId: 8
            },
          ], 
          //某一个部门的数据
          leftData: [
            {
              name: '张三',
              userId: 1
            },{
              name: '李四',
              userId: 2
            },{
              name: '王五',
              userId: 3
            },{
              name: '刘能',
              userId: 4
            },
          ],
       }
    },
    methods:{
       change(val) {
          this.value = val.map((item) => item.userId)
       },
       
    }
 }
</script>

子组件(主要)

  <template>
    <div class="out">
        <el-row :gutter="20">
            <el-col :span="11">
              <div class="left">
                <div class="table-transfer">
                   <span class="stuChoose">未选人员</span> 
                </div>
            </div>
            <div style="height: 400px; overflow:scroll;">
                <el-table
                border 
                size="mini"
                :data="leftData"
                @selection-change="handleLeftSelectionChange"
                >
                    <el-table-column type="selection" width="50" align="center" fixed="left" />
                    <div v-for="(item, index) in columns" :key="index">
                        <el-table-column 
                        v-if="item.visible" 
                        :label="item.label"
                        align="center" 
                        :prop="item.key" />
                    </div>
                </el-table>
            </div>
                
            </el-col>
            <el-col :span="2" class="btns">
                <el-button
                 class="btn" 
                 :disabled="leftMultiple" 
                 type="primary"
                 icon="el-icon-right" 
                 @click="moveToRight"
                 circle
                 ></el-button>
                 <el-button
                 class="btn"
                 :disabled="rightMultiple"
                 type="primary"
                 @click="moveToLeft"
                 icon="el-icon-back"
                 circle
               ></el-button>
            </el-col>
            <el-col :span="11">
                <div class="right">
                 <div class="table-transfer">
                   <span class="stuChoose">已选人员</span> 
                 </div>
                 <div style="height: 400px; overflow:scroll;">
                <el-table
                 border
                 size="mini"
                 :data="rightData"
                 @selection-change="handleRightSelectionChange"
                 >
                    <el-table-column type="selection" width="40" align="center" fixed="left" />
                    <div v-for="(item, index) in columns" :key="index">
                        <el-table-column :label="item.label" align="center" :prop="item.key" />
                    </div>
                </el-table>
               </div>
              </div>
            </el-col>
        </el-row>
    </div>

</template>
<script>
export default {
  props: {
        // 绑定数据
    value: {
      type: Array,
      default: () => []
    },
        // 主键key值
    keyName: {
      type: String,
      default: 'userId'
    },
        // 表格数据
    columns: {
      type: Array,
      default: () => []
    },
        /**
         * 是否显示搜索框
         */
    showSearch: {
      type: Boolean,
      default: true
    },
    allNumber: {
      type: Array,  //这是所有部门人员的数据
      default: () => []
    },
    leftDataRemain: {
      type: Array,  //左边的数据,由于这里是每个部门的数据
      default: () => []
    }
  },
  data () {
    return {
      dataList: [],
        // 左边的
      searchLeft: '',
      leftIds: [],
      leftMultiple: true,
      leftDataList: [],
      leftData: [],
//   右边的
      leftRemainArr: [],
      rightData: [],
      rightDataList: [],
      rightMultiple: true,
      rightIds: [],
      rightRemainArr: [],  
      Arr: []
    }
  },
  created () {
    this.init()
  },
  mounted () {

  },
  watch: {
    allNumber (old, newVal) {
      this.init()
    }
  },
  methods: {
    init () {
      this.rightIds = this.value
      for (let i = 0; i < this.allNumber.length; i++) {
        // this.optionsTeam.push(obj)
        if (this.value.some((item) => item === this.allNumber[i][this.keyName])) {
        //   console.log(this.allNumber[i][this.keyName], 'item')
          this.rightDataList.push(this.allNumber[i])
        }
      }
      this.leftDataList = this.leftDataRemain
      this.leftRemainArr = [...this.leftDataList]
      this.leftData = [...this.leftDataList]
      this.rightData = [...this.rightDataList]
      this.rightRemainArr = [...this.rightDataList]
    },
    // 这是我们选的要添加到右边的值
    handleLeftSelectionChange (selection) {
      this.leftIds = selection.map(item => item[this.keyName])
      this.leftMultiple = !selection.length
    },
    // right多选框选中数据
    handleRightSelectionChange (selection) {
      this.rightIds = selection.map((item) => item[this.keyName])
      this.rightMultiple = !selection.length
    },
    // 举个例子,当右移数据的时候,此时处理左边的数组
    arrJson (arr, attr, value) {
      if (arr) {
        let leftArr = arr.filter((item, index) => {
          return item[attr] !== value
        })
        return leftArr
      }
    },
    moveToLeft () {
        // 先把没选择的留下来,
      for (const rightIndex of this.rightIds) {
        this.rightRemainArr = this.arrJson(this.rightRemainArr, this.keyName, rightIndex)
      }
      this.rightDataList.forEach((rightItem, index) => {
        for (const rightIndex of this.rightIds) {
          if (rightItem.userId === rightIndex) {
            this.leftRemainArr.push(rightItem)
          }
        }
      }
        )
      this.leftData = this.leftRemainArr
      this.leftDataList = this.leftData
      this.rightData = this.rightRemainArr
      this.rightDataList = this.rightRemainArr
      this.$emit(
        'change',
        this.rightDataList
      )
    },

    // 向右移动
    moveToRight () {
    //   console.log('leftItem')
      for (const leftIndex of this.leftIds) {
        this.leftRemainArr = this.arrJson(this.leftRemainArr, this.keyName, leftIndex)
      }
      this.leftDataList.forEach((leftItem, index) => {
        // console.log(leftItem, 'leftItem')
        let leftIndex = this.leftIds.findIndex((item) => item === leftItem[this.keyName])

        if (leftIndex !== -1) {
          this.rightDataList.push(leftItem)
        }
      })
      this.rightRemainArr = this.rightDataList
      this.leftData = this.setData(this.leftRemainArr, this.searchLeft)
      this.rightData = this.rightDataList
    // let team = []
    // team = this.rightDataList

      this.$emit(
        'change',
        this.rightDataList
    )
    },

// 左边的查询
    handleQueryLeft () {
      this.leftData = this.setData(this.leftDataList, this.searchLeft)
    },
    // 查询datalist  查询这块还没写完,
    setData (dataList, search) {
    //   if (search != null || search !== '') {
    //     let list = []

    //     for (let i = 0; i < dataList.length; i++) {
    //       if (
    //         this.columns.some((item) =>
    //           dataList[i][item.key].includes(search)
    //         )
    //       ) {
    //         list.push(dataList[i])
    //       }
    //     }
    //     return list
    //   } else {
    //     return dataList
    //   }
      return dataList
    },
    resetData () {
      this.dataList = []
      this.leftDataList = []
      this.rightDataList = []
      this.leftData = []
      this.rightData = []
      this.searchLeft = ''
      this.leftIds = []
//   右边的
      this.leftRemainArr = []
      this.groupId = 0
      this.groupArr = []
      this.Arr = []
    }
  }
}
</script>
  
<style lang="scss" scoped>
.table-transfer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    .stuChoose{
        display: inline-block;
        width: auto;
        font-size: 18px;
        font-weight: 500;
    }
}

.btns {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    margin-bottom: -50px;
    .btn {
        margin: 20px 0;
        
    }
}
</style>