vue和element实现权限树的各种功能
权限树功能简介和说明
在工作开发的过程中,项目中需要用到权限管理的相关功能,因此去完成了权限树的开发。在开发中,主要运用vue和elementui进行开发,权限树先进行渲染,然后再完成各种功能。权限树选中父节点不一定选中子节点,选中子节点不一定选中父节点,包含选择和全选的功能,点击父节点一定会展开子节点的功能。
权限树的渲染
在element的权限树中,:data是权限树的内容,我的数据是通过接口从后台获取的对象,然后:default-checked-keys是权限树默认选中的内容,这个绑定的内容是一个数组,存储了权限树的id,也是权限树的唯一的标识,后端将有权限的内容也是以对象的形式传给前端的,所以我需要将此处的id用递归的形式提取出来,然后进行绑定。
<el-tree
:data="rightList"
:props="treeProps"
node-key="id"
ref="editTreeRef"
:default-expanded-keys="editKeys"
show-checkbox
:default-checked-keys="editKeys"
@check-change="checkChange"
check-strictly
check-on-click-node
></el-tree>
data() {
return {
// 权限树的全部的渲染内容
rightList: [],
// 后台传过来的用户有的权限
roleRightList: [],
// 用户默认含有的权限,为数组类型,需要进行递归获取
editKeys: []
}
},
methods: {
// 将后台传过来的数组对象进行id提取,放入到数组中
getEditKeys() {
for (let i = 0; i < this.roleRightList.length; i++) {
this.getLeafKeys(this.roleRightList[i], this.editKeys)
}
},
// 获取权限的id,将其放入数组中
getLeafKeys(node, arr) {
// 在此处后端给我传的数据存在两种情况,一种是没有子数组了,另一个就是子数组的长度为0,所以两种都需要判断
if (!node.list || node.list.length === 0) {
return arr.push(node.id)
}
// 递归继续
node.list.forEach(item => {
arr.push(node.id)
this.getLeafKeys(item, arr)
})
},
}
权限树的父子关联说明
在此权限树中,我做的是选中父节点,父节点下的子节点展开,选择子节点,父节点一定会选中, 取消父节点,子节点一定全部取消。所以我先在element中先设置check-strictly来进行父子进行关联,然后通过@check-change的事件来对选中其进行控制。具体的操作和解释可以看代码和注释的相关内容。
// 当权限树中的勾选情况发生改变的时候
checkChange(node, check) {
if(check === true) {
// 当子节点选中的时候,父节点必须选中
this.$refs.editTreeRef.setChecked(node.resourceParentId, true)
// 当父节点选中的时候,父节点下的子节点需要进行展开处理
// 可以将refs.editTreeRef打印出来去找里面的数据,然后能发现控制展开的数据
this.$refs.editTreeRef.store.nodesMap[node.id].expanded = true
}
// 判断是否含有子节点需要先判断是否有子列表,子列表是否有长度,这个位置根据后端数据的处理相关
if(node.list) {
if(node.list.length !== 0) {
// 若父节点取消选中,子节点也需要取消选中
if(check === false) {
for( let i=0; i<node.list.length; i++) {
this.$refs.editTreeRef.setChecked(node.list[i].id, false)
}
}
}
}
}
通过递归来实现权限树的全选
首先我需要在整个权限树的前面加上一个el-checkbox来实现对整个权限树的全选与取消进行控制,首先需要双向绑定一个bool值来进行判断,然后绑定change事件对整个权限树进行控制。
其中还有如果权限树全选中后,checkbox自动勾选选中,如果权限树没有全选中,checkbox会自动取消勾选。
首先需要通过递归来获取整个权限树的权限个数,由于父节点和子节点都有相对应的权限,所以需要每个权限都进行获取。
然后再对每个权限树来进行权限获取的计算,初始的数值为0,若全选或者全取消则赋值为总权限树的值,或者为0,然后@check-change来进行计数判断。
通过监听来判断checkbox是否选中,其中注意是否会有溢出的情况
watch: {
editflag(val) {
if(val >= this.flag) {
this.editflag = this.flag
this.editChecked = true
} else {
this.editChecked = false
if(val <= 0) {
this.editflag = 0
}
}
}
},
递归获取权限的个数
// 获取权限树的权限的个数
getAllNumber(node) {
// 跳出递归的条件
if( !node.list || node.list.length === 0 ) {
return
}
// 还是通过递归来统计权限的个数
node.list.forEach(item => {
this.flag++
this.getAllNumber(item)
})
},
剩下的统计部分就是会添加到@check-change事件中去写,根据check=true或者false来进行增加或者减少,这大概就是去写全选的所有思路。
权限树总结
感觉目前应该是考虑到了一棵权限树的全部的功能,如果有添加还需要继续去补充完善,虽然单看每一个功能都不是很难,但是很多地方都特别的细节,在开发的过程中仍然会遇到不小的困难,也算是给自己留个记录,方便下次开发到同类型的功能进行使用。