問題描述:
在寫后臺管理是 遇到用el-tree展示權(quán)限列表的情況爸舒,給角色分配權(quán)限時,選擇了某一項目前全有的權(quán)限稿蹲,如圖:
但是如果之后 我再新增一個子權(quán)限 這個子權(quán)限也會被默認選中扭勉,如圖:
首先新增一個 但是我并沒有去給任何角色分配此權(quán)限
但是:!苛聘!what the f**k??
產(chǎn)生原因:當(dāng)我們在全部選中某一項權(quán)限時 權(quán)限的父級id也會被加入到我們已選擇的權(quán)限中 當(dāng)我們把含有父級id的權(quán)限數(shù)組傳給后端涂炎,再請求權(quán)限列表時忠聚,el-tree檢測到里面包含的父級權(quán)限的id,就會默認勾選上該父級權(quán)限及他下面的所有子權(quán)限唱捣。
解決辦法:
辦法1:取消父子級聯(lián)動效果 使用 check-strictly 屬性两蟀,
<el-tree
ref="tree"
:data="listPermission"
:props="props"
node-key="permissionId"
show-checkbox
default-expand-all
:default-checked-keys="hadPermissionIdList"
getCheckedKeys
check-strictly
></el-tree>
辦法2,在添加權(quán)限和顯示已有權(quán)限時 過濾掉父級id
第一步震缭,在上傳id的時候 過濾掉父級id 這樣在之后請求權(quán)限列表時就不會有父級id存在赂毯,上述問題就不會存在了。但是拣宰,會有一個新的bug党涕,如果有一個權(quán)限,情況一:他有子級巡社,但是目前子級目前還沒有添加上去膛堤,也就是他的haveChildFlag 為true,但是目前childList為[ ],或者重贺,情況二:原本是子級骑祟,haveChildFlag 為false,后來子級變?yōu)楦讣?haveChildFlag 為true气笙。那么這樣的父級我們都應(yīng)該先視為子級次企,等他變?yōu)楦讣壷螅∠倪x中狀態(tài)潜圃,等待管理員重新分配角色缸棵,否則,還是會出現(xiàn)有了父級id谭期,子級(不論是否是新增)被全部選中的情況堵第。
具體實現(xiàn)思路:在提交選中的權(quán)限的時候,過濾掉childList.length>0的父級隧出。在請求到權(quán)限之后踏志,過濾掉已有權(quán)限中childList.length>0的父級。
<template>
<div>
<el-button type="warning" @click="showDialog">分配權(quán)限</el-button>
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
<el-tree
ref="tree"
:data="listPermission"
:props="props"
node-key="permissionId"
show-checkbox
default-expand-all
:default-checked-keys="hadPermissionIdList"
getCheckedKeys
></el-tree>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="handleSubmit">確 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { updateUser,getlistPermission, appointPermissionToRole,} from "@/network/systemManage";//這是我封裝的網(wǎng)絡(luò)請求 用的axios
export default {
props: ["row"],
data() {
return {
dialogVisible: false,
data: [],
selectedRole: [],
props: {
label: "permissionName",
children: "childList",
},
count: 1,
listPermission: [], //權(quán)限列表(所有)
hadPermissionIdList: [], //已有的權(quán)限
permissionIdList: [], //要選擇的權(quán)限
toDeletePermissionIdList: [], //被刪掉的權(quán)限
lock: false//防止重復(fù)點擊的鎖
};
},
created() {},
methods: {
showDialog() {//打開彈窗
this.dialogVisible = true;
this.lock = false;
const config = {
pageIndex: 1,
pageSize: 10,
roleId: this.row.id,
};
getlistPermission(config).then((res) => { //獲取某用戶權(quán)限列表
const data = res.data;
if (data.code == 100) {
//全部權(quán)限
this.listPermission = data.content.allPermissionList;
//該用戶已有權(quán)限
if (data.content.hadPermissionIdList) {
this.hadPermissionIdList = data.content.hadPermissionIdList;
//過濾父級id
let newArr = [];
let item = "";
this.hadPermissionIdList.forEach((item) => {
this.checked(item, this.listPermission, newArr);
}); //item是已有的id胀瞪,將已有的id與全部id進行匹配 找出父id然后刪除
this.hadPermissionIdList = newArr; //將刪除了父級id的數(shù)據(jù)賦值過去针余,這樣就不會選中父id下面的東西了。
}
}
});
},
checked(id, data, newArr) {//這個函數(shù)是在檢查id是否是父級id 將子級id過濾出來 運用到了遞歸
data.forEach((item) => {
if (item.permissionId == id) { //在數(shù)組的第一層中查找屬于這個id的item
if (!item.haveChildFlag || item.childList.length < 1) {//如果item沒有子級或者子級為空就說明他不是父節(jié)點或者暫時不是父節(jié)點 因為也存在有子級但是子級還沒有添加進去的情況 如果直接過濾掉haveChildFlag 為true的item 會導(dǎo)致判斷不精準(zhǔn)
newArr.push(item.permissionId);
}
} else {
if (item.haveChildFlag && item.childList.length != 0) {
// 查找第二層 第三層 檢查這個id是否是子節(jié)點的id
this.checked(id, item.childList, newArr);
}
}
});
},
handleSubmit() {
//點擊確定 發(fā)送配置權(quán)限時
//獲取選中的角色
if (!this.lock) {//這個lock是為防止重復(fù)點擊
var selectedRoleAll = [];
this.selectedRole = [];
this.lock = true;
//獲取所有被選中的權(quán)限
selectedRoleAll = this.$refs.tree.getCheckedNodes();
//將是子級 或者是父級但是還沒有添加子級(這種要暫時將他視為子級 等他真正添加了子級之后 再刪除)的id過濾出來
selectedRoleAll.forEach((item) => {
if (item.childList.length === 0) {
this.selectedRole.push(item);
}
});
let arr = [];
//拿到他們的id
this.selectedRole.map((item) => {
arr.push(item.permissionId);
});
// console.log("已選擇" + arr);
// 對比原本有的和現(xiàn)在選擇的 篩選出原來有的現(xiàn)在沒有的//這是個人需求 后端要求我在傳送選擇了哪些權(quán)限時將原本有現(xiàn)在沒有了的權(quán)限一起返給他
this.toDeletePermissionIdList = this.hadPermissionIdList.filter(
(item) => {
return arr.indexOf(item) == -1;
}
);
// console.log("被刪掉" + this.toDeletePermissionIdList);
const config = {
permissionIdList: arr,
roleId: this.row.id,
toDeletePermissionIdList: this.toDeletePermissionIdList,
};
// 發(fā)送請求
appointPermissionToRole(config).then((res) => {
const code = res.data.code;
if (code == 100) {
this.dialogVisible = false;
this.$message({
message: res.data.message,
type: "success",
});
} else {
this.$message.error(res.data.message);
}
});
} else {
return;
}
},
},
};
</script>
<style>
</style>
另一種需求
如果后端要求在上傳權(quán)限id時凄诞,不能過濾掉父級id圆雁,那么應(yīng)該對代碼做出修改。
經(jīng)過調(diào)試發(fā)現(xiàn)帆谍,使用
var selectedRoleAll = this.$refs.tree.getCheckedNodes();
el-tree只有在子節(jié)點全選中時峻呕,父節(jié)點才是選中狀態(tài)吭敢,selectedRoleAll 中才會有父節(jié)點id吉拳,當(dāng)取消一個子節(jié)點,父節(jié)點就變成了半選狀態(tài)朴肺,此時,應(yīng)當(dāng)使用:
var parentArr = this.$refs.tree.getHalfCheckedNodes()
來獲取子父節(jié)點跃脊,然后將兩者的id提出來宇挫,進行拼接,再將拼接后的數(shù)據(jù)上傳
[半選節(jié)點(父級)id].concat([子節(jié)點id]),
注意再看一遍我的屬性配置
<el-tree
ref="tree"
:data="listPermission"
:props="props"
node-key="permissionId"
show-checkbox
default-expand-all
:default-checked-keys="hadPermissionIdList"
getCheckedKeys
@check-change="checkChange"
></el-tree>
這樣就能在子元素非全選的情況下將父節(jié)點id上傳酪术,但是這樣在請求到以后權(quán)限的時候,為了避免出現(xiàn)之前的bug翠储,需要將父節(jié)點id過濾出來再綁定到
default-checked-keys上绘雁,方法與第一種情況中給的一樣,不再贅述援所。
數(shù)據(jù):
"content":{
"allPermissionList":[
{
"childList":[
{
"childList":[],//子級列表
"haveChildFlag":false,///根據(jù)這個字段判斷是不是有沒有子級
"menuFlag":true,
"modelAction":"admin/listRole",
"parentLevelId":1,
"permissionId":2,
"permissionName":"角色管理"
},
{
"childList":[],
"haveChildFlag":true,
"menuFlag":true,
"modelAction":"admin/listPermission",
"parentLevelId":1,
"permissionId":8,
"permissionName":"菜單管理"
},
],
"haveChildFlag":true,
"menuFlag":true,
"modelAction":"admin",
"parentLevelId":0,
"permissionId":1,
"permissionName":"系統(tǒng)管理"
},
{
"childList":[
{
"childList":[],
"haveChildFlag":false,
"menuFlag":false,
"modelAction":"terminal/listTerminal",
"parentLevelId":6,
"permissionId":7,
"permissionName":"設(shè)備列表"
},
],
"haveChildFlag":true,
"menuFlag":true,
"modelAction":"terminal",
"parentLevelId":0,
"permissionId":6,
"permissionName":"設(shè)備管理"
},
{
"childList":[
{
"childList":[
{
"childList":[],
"haveChildFlag":false,
"menuFlag":true,
"modelAction":"dispathTask/yinliu/follow",
"parentLevelId":61,
"permissionId":63,
"permissionName":"關(guān)注功能"
}
],
"haveChildFlag":true,
"menuFlag":true,
"modelAction":"executeTask/yinliu",
"parentLevelId":59,
"permissionId":61,
"permissionName":"引流功能"
},
{
"childList":[],
"haveChildFlag":false,
"menuFlag":true,
"modelAction":"dispathTask/danxiang",
"parentLevelId":59,
"permissionId":66,
"permissionName":"單項功能"
},
],
"haveChildFlag":true,
"menuFlag":true,
"modelAction":"dispathTask",
"parentLevelId":0,
"permissionId":59,
"permissionName":"任務(wù)下發(fā)"
},
{
"childList":[],
"haveChildFlag":false,
"menuFlag":false,
"modelAction":"admin/getCurrentUserInfo",
"parentLevelId":0,
"permissionId":78,
"permissionName":"獲取當(dāng)前用戶信息"
},
]
},