在日常开发项目中,特别是有些后台管理系统,常用到项目流程中需要添加的子级(或者称为二级菜单),此场景可有效帮助你了解如何使用递归实现表格元素的二级。
需求: 用户可在项目应用点中,添加至三级菜单,其中序号实现自增并且实现对父级下的多层菜单实现编辑删除操作。(父级元素不可操作)
本人编写的这个项目因为需求,所以采用遍历后的item,源数据为tableData,所以el-table中的:data绑定为item,分类显示,若没有这个需求,则正常绑定后端传来的数据源即可,此处合并了数据,所以item便是等同于从后端请求过来的数据。大家可以根据自己的需求来编写html(此处不是重点!)
此处为实现分类编排列表的方法(非必要,大家按自身需求编写)
//按照计划阶段(planStage)进行分组
filterProgress(data) {
const typeList = ['previous', 'desgin', 'build']
const grouped = {
previous: [],
desgin: [],
build: []
}
data.forEach((item) => {
grouped[typeList[item.planStage - 1]]
? null
: (grouped[typeList[item.planStage - 1]] = [])
grouped[typeList[item.planStage - 1]].push(item)
})
return grouped
},
接下来先编写排序方法,让表格中排序一列绑定的prop进行自增序号,定义setSort()
方法,用于给输入的数据 data
数组中的每个元素添加一个新的 newSort
属性,并根据传入的 count
参数为每个元素生成排序值。
具体来说,方法首先使用 map
方法遍历 data
数组中的每个元素,对每个元素进行处理:
- 根据传入的
count
参数,生成一个新的排序值newSort
。如果count
存在,则将count
和当前元素在数组中的索引值(加一)拼接作为新的排序值;否则,直接使用当前元素在数组中的索引值(加一)作为排序值。 - 如果当前元素具有
childList
属性且其长度大于 0,则递归调用setSort
方法处理子元素,并将生成的排序值传递给子元素。
最后,方法返回一个新的数组 newArr
,其中包含了对输入数组 data
中每个元素添加了新的 newSort
属性后的结果。定义的排序方法方便后续在buildTreeData()方法中调用
setSort(data, count) {
const newArr = data.map((item, index) => {
const newSort = count ? count + '.' + (index + 1) : index + 1
if (item.childList.length > 0) {
item.childList = this.setSort(item.childList, newSort)
}
return {
...item,
newSort: newSort
}
})
return newArr
},
接着是编写buildTreeData()方法来实现构建树形数据结构,接受一个对象 obj
和一个可选的 level
参数作为输入。方法的作用是遍历对象 obj
中的每个键值对,对值进行处理,以构建树形结构的数据。具体来说,方法使用了一个 for...in
循环来遍历 obj
对象的属性。在循环中,首先判断当前属性值是否为数组,如果是数组,则遍历数组中的每个元素(通过 forEach
方法),对每个元素进行处理:
- 将元素的
level
属性设置为当前传入的level
值。 - 如果元素有
childList
属性且其长度大于 0,则递归调用buildTreeData
方法,传入一个包含childList
的对象,并将level
值加一,以处理子节点的数据。
接着,对每个键对应的值进行排序操作,使用 this.setSort
方法对数组进行排序,并将排序后的数组重新赋值给 obj[key]
。
最终,方法会对 obj
中的每个键值对进行处理,包括设置 level
属性和对数组进行排序,以构建完整的树形数据结构。
// 递归设置level
buildTreeData(obj, level = 1) {
for (const key in obj) {
if (Array.isArray(obj[key])) {
obj[key].forEach((item) => {
item.level = level
if (item.childList && item.childList.length > 0) {
this.buildTreeData({ child: item.childList }, level + 1)
}
})
}
obj[key] = this.setSort(obj[key].sort((a, b) => a.sort - b.sort))
}
},
最后就是调用编写的方法,达到添加子级的效果
注:此处的list为请求数据的接口方法,大家可自行替换,user的处理大家也可以删除掉
init() {
const { progressId } = this
if (progressId === undefined) {
this.$emit('toggleComponent', true)
}
const progerss = list(progressId)
const user = getTeam(progressId)
Promise.all([progerss, user]).then(([listResult, usersResult]) => {
const data = listResult.entities
this.tableData = this.filterProgress(data)
this.buildTreeData(this.tableData)
this.userList = usersResult.entities.filter((item, index, self) => {
return self.findIndex((obj) => obj.userId === item.userId) === index
})
})
},
文章到这里就结束了,大家如果觉得哪里写得不好可以留言哦!
共同学习,共同成长!