1、彈出分配權限的對話框並請求權限數據
先給分配按鈕添加點擊事件:
<el-button size="mini" type="warning" icon="el-icon-setting" @click="showSetRightDialog(scope.row.id)">分配權限</el-button>
添加分配權限對話框:
<!--分配角色權限的對話框--> <el-dialog title="分配權限" :visible.sync="setRightDialogVisible" width="50%"> <!--內容主體區域--> 111 <!--底部按鈕區域--> <span slot="footer" class="dialog-footer"> <el-button @click="setRightDialogVisible = false">取 消</el-button> <el-button type="primary" @click="setRightDialogVisible = false">確 定</el-button> </span> </el-dialog> <script> export default { data() { return { setRightDialogVisible: false, // 控制分配角色權限對話框是否顯示 rightsList: [] // 角色所有權限數據 } }, methods: { // 展示分配權限的對話框 async showSetRightDialog(id) { this.setRightDialogVisible = true // 獲取所有權限列表 樹形 const { data: res } = await this.$http.get('rights/tree') console.log(res) if (res.meta.status !== 200) { return this.$message.error('獲取權限列表失敗') } this.rightsList = res.data } } } </script>
2、分配並使用el-tree樹形控件
先把Tree添加引入到element.js,這里就不寫了。
然后找到el-tree的實例代碼:show-checkbox 節點是否可被選擇
<!--內容主體區域 樹形控件--> <el-tree :data="rightsList" :props="defaultProps" show-checkbox></el-tree> <script> export default { data() { return { // 樹形控件的屬性綁定對象 treeProps: { label: 'authName', children: 'children' } } } } </script>
效果圖:
3、優化樹形控件的顯示UI
node-key 每個樹節點用來作為唯一標識的屬性,整棵樹應該是唯一的
default-expand-all 是否默認展開所有節點
<!--內容主體區域 樹形控件--> <el-tree :data="rightsList" :props="treeProps" show-checkbox default-expand-all node-key="id"></el-tree>
4、加載當前角色的已有權限
default-checked-keys 默認勾選的節點的 key 的數組
<!--內容主體區域 樹形控件--> <el-tree :data="rightsList" :props="treeProps" show-checkbox default-expand-all :default-checked-keys="defKeys" node-key="id"></el-tree> <script> export default { data() { return { defKeys: [] // 默認選中的節點ID值數組 } } } </script>
把權限的id放入到defKeys數組中。
點擊分配權限按鈕的同時,把當前角色已有的三級權限的id都放入到defKeys數組中。
// 展示分配權限的對話框 async showSetRightDialog(role) { // 獲取所有權限列表 樹形 const { data: res } = await this.$http.get('rights/tree') // console.log(res) if (res.meta.status !== 200) { return this.$message.error('獲取權限列表失敗') } this.rightsList = res.data // 嵌套循環獲取三級節點的id var arr = [] // console.log(role.children) var children1 = role.children for (var i = 0; i < children1.length; i++) { var children2 = children1[i].children // console.log(children2) for (var j = 0; j < children2.length; j++) { var children3 = children2[j].children // console.log(children3) for (var k = 0; k < children3.length; k++) { arr.push(children3[k].id) } } } this.defKeys = arr this.setRightDialogVisible = true },
也可以先創建一個遞歸函數:
// 通過遞歸的形式,獲取角色下所有三級權限的id,並保存到defKeys數組中 getLeafKeys(node, arr) { // 節點 數組 // 如果當前node節點不包含children屬性,則是三級權限節點 if (!node.children) { return arr.push(node.id) } // 循環node里的children數組,每循環一項拿到一個子節點item,在根據item再次調用遞歸函數getLeafKeys, // 然后把當前的item當做一個節點傳進去,同時把arr傳進去。只要遞歸完畢后,就把三級節點的id都保存到arr了 node.children.forEach(item => this.getLeafKeys(item, arr)) }
然后調用遞歸函數:
// 展示分配權限的對話框 async showSetRightDialog(role) { // 獲取所有權限列表 樹形 const { data: res } = await this.$http.get('rights/tree') console.log(res) if (res.meta.status !== 200) { return this.$message.error('獲取權限列表失敗') } this.rightsList = res.data // 遞歸獲取三級節點的id this.getLeafKeys(role, this.defKeys) this.setRightDialogVisible = true },
分配權限按鈕加上scope.row:
<el-button size="mini" type="warning" icon="el-icon-setting" @click="showSetRightDialog(scope.row)">分配權限</el-button>
此時點擊分配按鈕,彈出的對話框如圖:
5、小bug,在關閉分配權限對話框時重置defKeys數組為空
給對話框綁定close事件:
<!--分配角色權限的對話框--> <el-dialog title="分配權限" :visible.sync="setRightDialogVisible" width="50%" @close="showSetRightDialogClosed">
showSetRightDialogCloseds事件:
// 監聽 分配權限對話框的關閉事件 showSetRightDialogClosed() { this.defKeys = [] }
當然也可以在打開對話框的時候清空defkeys數組,意思是一樣的。
6、調用api接口完成分配權限功能
角色授權接口,請求路徑:roles/:roleId/rights,請求方法:post,參數rids 權限 ID 列表(字符串) 以 `,` 分割的權限 ID 列表(獲取所有被選中、葉子節點的key和半選中節點的key, 包括 1,2,3級節點)
rids 權限 ID 列表:就是說所有選中和半選中狀態的id,然后以','分割
getCheckedKeys
若節點可被選擇(即 show-checkbox 為 true),則返回目前被選中的節點的 key 所組成的數組
(leafOnly) 接收一個 boolean 類型的參數,若為 true 則僅返回被選中的葉子節點的 keys,默認值為 false
getHalfCheckedKeys
若節點可被選擇(即 show-checkbox 為 true),則返回目前半選中的節點的 key 所組成的數組
給樹形控件添加引用:
<!--內容主體區域 樹形控件--> <el-tree :data="rightsList" :props="treeProps" node-key="id" show-checkbox default-expand-all :default-checked-keys="defKeys" ref="treeRef"></el-tree>
給確定按鈕添加點擊事件:
<el-button type="primary" @click="allotRigths">確 定</el-button>
添加allotRigths事件:
// 點擊按鈕 給角色分配權限 async allotRigths(id) { const keys = [ ...this.$refs.treeRef.getCheckedKeys(), ...this.$refs.treeRef.getHalfCheckedKeys() ] console.log(keys) }
此時選擇添加商品、商品修改、商品刪除3個權限,點擊確定,控制台會打印出keys數組,如下圖:
然后要把keys數組的值形成一個以","拼接字符串:
const idStr = keys.join(',')
再調用角色授權接口,把Keys數組傳遞給rids參數:
還有請求路徑要帶角色ID,但是我們在確定按鈕哪里獲取不到角色ID,只能在點擊分配按鈕的時候,先把角色ID傳出來
<script> export default { data() { return { roleId: '' // 當前角色id } }, methods: { // 展示分配權限的對話框 async showSetRightDialog(role) { this.roleId = role.id // 獲取角色id 。。。 } } </script>
然后請求接口:
// 點擊按鈕 給角色分配權限 async allotRigths() { const keys = [ ...this.$refs.treeRef.getCheckedKeys(), ...this.$refs.treeRef.getHalfCheckedKeys() ] // console.log(keys) const idStr = keys.join(',') const { data: res } = await this.$http.post(`roles/${this.roleId}/rights`, { rids: idStr }) if (res.meta.status !== 200) { return this.$message.error('更新角色權限失敗!') } this.$message.success('更新角色權限成功!') this.getRolesList() this.setRightDialogVisible = false }
效果圖: