开发中,经常有穿梭框的需求,但常见的灵活性较低,不支持左右树形,因此在项目开发过程中,摸索了treeTransfer库,是基于element组件库的。
如下图所示
树形穿梭框
treeTransfer安装
- 安装elementUi后,npm i el-tree-transfer
- 在页面使用引入,import treeTransfer from 'el-tree-transfer'
- 在conponents注册组件,components: {treeTransfer}
- 完成以上,便可在template中使用<treeTransfer></treeTransfer>
treeTransfer使用
H5部分,均在data中定义 title: ['所有指标', '已选指标'] 为左右头部描述:from_data='fromData'fromData为左侧数据(数组):to_data='toData' toData为右侧数据(数组)height='540px' 可为穿梭框设置高度filter开启过滤筛选(搜索)openAll展开所有节点
<treeTransfer
:title="title"
:from_data='fromData'
:to_data='toData'
:defaultProps="{label:'label'}"
@add-btn='add'
@remove-btn='remove'
:mode='mode'
height='540px'
filter
openAll
>
</treeTransfer>
实现左右树形
思路:进入树形穿梭框页面,获取所有的数据(左侧右侧数据在一个大数组),每一项有一个标识selected(selected为后端定义)为true时在右侧,所以在进入页面后,写两个方法,分别把数据放到左侧fromData和右侧toDat。实现在下方
数据结构
dataList为所有数据,最外层的父级pid必须是0(文档规定,且父级pid:0必须是Number类型),每一级的子级pid需要一致(自行看数据悟,数据都是很简单的),selected为当前项需要在右侧
dataList: [
{
id: '1',
pid: 0,
label: '界面指标',
children: [
{
id: '1-1',
pid: '1',
label: '隐藏存款',
selected: true
// disabled: true,
},
{
id: '1-2',
pid: '1',
label: '结算备用金'
}
]
},
{
id: '2',
pid: 0,
label: '隐藏指标',
children: [
{
id: '2-1',
pid: '2',
label: '赎回分红提前冻结T1'
// disabled: true,
},
{
id: '2-2',
pid: '2',
label: '申购分红款T0交收',
selected: true
}
]
}
],
实现左侧fromData展示
我这里是写了一个方法
参数一:treeList是总数据(上面的dataList),
参数二:leftFromDta是一个空数组(直接传空数组就好)
递归循环,父级到子级,将selected为false的一项,生成新数组并赋值给fromData
/**
* 格式化左侧数据
* @param {array} treeList
* @param {array} leftFromData
*/
getTreeList (treeList, leftFromData) {
treeList.map((item) => {
if (!item.selected) {
const tempData = {
label: item.label,
id: item.id,
pid: item.pid
}
// 如果有子项
if (item.children && item.children.length > 0) {
tempData.children = []
this.getTreeList(item.children, tempData.children)
}
leftFromData.push(tempData)
}
})
this.fromData = leftFromData
},
实现右侧toData展示
参数与左侧一致
思路是在数据中找到selected为true的一项,并生成一个对象(对象需要父级包子级的格式),所以需要两层循环,children(数组)为当前找到selected为true的一项,并push在数组中
注意:最后生成的数组,需要去重一下,我这里用的是lodash提供的方法
可自行去重,去重后赋值给toData即可
/**
* 格式化右侧todata
* @param {array} treeList
* @param {array} rightToData
*/
getToDataList (treeList, rightToData) {
let childrenArr = []
// 一级
treeList.forEach((element) => {
// 二级
element.children.forEach(item => {
if (element.id === item.pid && item.selected) {
childrenArr.push(item)
const tmp = {
label: element.label,
id: element.id,
pid: element.pid,
children: childrenArr
}
rightToData.push(tmp)
}
})
childrenArr = []
})
// 引用类型数组去重
this.toData = _.uniqWith(rightToData, _.isEqual)
},
到此,进入页面默认展示左侧、右侧已完成。
左右穿梭后,可打印fromData、toData来查看当前左右侧数据