在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>