需求:左边一个树结构,右边一个穿梭框,穿梭框嵌套表格,点击树节点获取穿梭框数据。如下图所示:
本文使用的组件是TDesign Web Vue中的穿梭框组件。
通过官网了解到,t-design的穿梭框可以嵌套树节点,那么也可以通过插槽来嵌套表格
在穿梭框嵌套表格时,必须绑定row-key值,否则表格选择有问题。如果不知道唯一键是什么,可以在插槽中渲染slotProps值,来查看唯一键字段名。
还有一个点值得注意的是,在最初实现的时候,发现加了row-key之后可以多选,但是表格多选并没有和穿梭框结合起来,表格多选几条数据,穿梭框中带穿梭数量还是为0,这是因为表格多选绑定的数据是selectedRowKeys,但是穿梭框没有绑定,因此无法关联起来,所以在穿梭框通过:checked.sync="selectedRowKeys"将多选数据绑定起来,就可以达到关联的效果。
代码如下:
<t-transfer
theme="primary"
:data="tableData"
v-model="formItem.userDetail"
:checked.sync="selectedRowKeys" //多选
:onPageChange="handlePageChange"
:search="true"
:keys="{ label: 'searchName', value: 'id' }"
@change="onChange"
@checked-change="handleCheckedChange"
:pagination="pagination"
>
<template v-slot:tree="slotProps">
<t-table
height="380"
v-bind="slotProps"
row-key="value" //必须
:columns="columns"
:selected-row-keys="selectedRowKeys"
@select-change="rehandleSelectChange"
>
<template #name="slotProps">
//获取数据路径不一定,可以自己先渲slotProps来查看具体
<span>{{slotProps.row.data.name}}</span>
</template>
<template #mobile="slotProps">
<span>{{slotProps.row.data.mobile}}</span>
</template>
<template #deptId="slotProps">
<span>{{slotProps.row.data.dept}}</span>
</template>
</t-table>
</template>
</t-transfer>
data(){
return {
tableData:[] //表格数据
}
}
至此,穿梭框嵌套表格就已经完成。
这时有个新需求,都知道穿梭框右边的数据是来源于穿梭框左边的数据,而在该项目中,穿梭框数据是通过点击树节点来获取,如果切换树节点,则会导致穿梭框右边已选的数据显示为空。而需求是切换树节点,已选的节点保持不变。
说一下思路:通过点击树节点获取穿梭框来源数据,而已选的来自于穿梭框左边,当切换树节点时,可以通过将穿梭框已选的数据push到tableData(表格数据)中去,这样切换树节点的时候,表格数据一直是穿梭框已选的数据,就可以达到切换树节点,但是穿梭框已选数据不变的效果。
具体实现:
//树节点点击事件
onTreeClick(context) {
console.log(context);
// 将已选的节点复制给checked数组
this.checked = this.formItem.userDetail
//因为已选的数组是为id,所以得把表格数据过滤一下,通过checkObj把已选的数据对象存储
this.checkedObj = this.tableData.filter(val=>{
return this.checked.includes(val.id)
})
this.selectedIds = context.id
// 调用获取数据的方法
this.getUser(context.id)
},
// 点击树获取用户数据
getUser(id){
let url = `url地址`
let msg = this.$Message.loading({
content:'正在获取数据',
duration:0
})
this.$http.get(url).then(res=>{
msg()
let data = res.data.data
// 把获取到的和之前已选的组合在一起 并且去重
this.tableData = this.uniqueArr(data,this.checkedObj)
//给每一项都加一个字段
this.tableData = this.tableData.map(item=>{
return {
...item,
searchName:item.name + item.dept+ item.mobile //搜索时用
}
})
// 再把checked数组赋值给穿梭框的绑定值
this.formItem.userDetail = this.checked
}).catch(err=>{
msg()
})
},
对象数组去重 :
// 去重
uniqueArr(arr1,arr2){
let arr = arr1.concat(arr2)
let newArr = []
for (let item of arr) {
let flag = true
for (const item1 of newArr) {
if(item.id == item1.id){
flag = false
}
}
if(flag){
newArr.push(item)
}
}
return newArr
},
至此,就达到了切换树节点,但是已选数据不变的效果。
还有个问题,这个穿梭框是可搜索的穿梭框,t-design组件库中自带搜索的方法:search
keys用来定义选项文本和选项值字段,给穿梭框绑定keys。
在测试搜索的时候发现,keys定义的label字段名是什么,则搜索就通过该字段来搜索。但是要求是搜索框能搜索姓名、电话以及部门。
解决办法,通过给表格数据每一项都加一个字段,该字段为姓名、电话以及部门的结合:如下
有问题欢迎指出~