1、通過路由展示角色列表組件
新建roles.vue文件:
<template> <div> <h3>角色列表組件頁面</h3> </div> </template> <script> export default { } </script> <style scoped> </style>
添加角色列表路由:
import Roles from '../components/power/roles.vue' const routes = [ { path: '/', redirect: '/login' }, // 重定向 { path: '/login', component: Login }, { path: '/home', component: Home, redirect: '/welcome', // 重定向 children: [ // 子路由 { path: '/welcome', component: Welcome }, { path: '/users', component: Users }, // 用戶列表 { path: '/rights', component: Rights }, // 權限列表 { path: '/roles', component: Roles } // 角色列表 ] } ]
點擊左側菜單的角色列表,效果如圖:
2、繪制基本布局並獲取角色列表數據
先實現基本布局,還是面包屑和卡片視圖:
<template> <div> <!--面包屑導航區域--> <el-breadcrumb separator-class="el-icon-arrow-right"> <el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item> <el-breadcrumb-item>權限管理</el-breadcrumb-item> <el-breadcrumb-item>角色列表</el-breadcrumb-item> </el-breadcrumb> <!--卡片視圖區域--> <el-card> <!--添加角色按鈕區域--> <el-row> <el-col> <el-button type="primary">添加角色</el-button> </el-col> </el-row> <!--用戶列表區域--> </el-card> </div> </template>
添加獲取方法:
通過調用api接口獲取角色列表,請求路徑:roles,請求方法:get
<script> export default { data() { return { rolesList: [] // 角色列表數據 } }, created() { this.getRolesList() }, methods: { async getRolesList() { const { data: res } = await this.$http.get('roles') console.log(res) if (res.meta.status !== 200) { this.$message.error('獲取角色列表失敗') } this.rolesList = res.data } } } </script>
3、渲染角色列表數據
添加角色列表的表格區域:
<!--用戶列表區域--> <el-table :data="rolesList" style="width: 100%" border stripe> <el-table-column type="index" label="#"></el-table-column> <el-table-column prop="roleName" label="角色名稱"></el-table-column> <el-table-column prop="roleDesc" label="角色描述"></el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> </template> </el-table-column> </el-table>
操作列里面要放置三個帶圖標的按鈕:
<el-table-column label="操作" width="320"> <template slot-scope="scope"> <el-button size="mini" type="primary" icon="el-icon-edit">編輯</el-button> <el-button size="mini" type="danger" icon="el-icon-delete">刪除</el-button> <el-button size="mini" type="warning" icon="el-icon-setting">分配權限</el-button> </template> </el-table-column>
再添加第一列的展開按鈕列:
<!--用戶列表區域--> <el-table :data="rolesList" style="width: 100%" border stripe> <!--展開列--> <el-table-column type="expand"></el-table-column>
效果如圖:
4、實現添加角色功能
因為前面實現過添加用戶的功能,所以這里就簡單寫了。
添加角色按鈕添加點擊事件:
<el-button type="primary" @click="addDialogVisible = true">添加角色</el-button>
添加對話框代碼:
<!--添加角色的對話框--> <el-dialog title="添加角色" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed"> <!--內容主體區域--> <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="90px"> <el-form-item label="角色名稱" prop="roleName"> <el-input v-model="addForm.roleName"></el-input> </el-form-item> <el-form-item label="角色描述" prop="roleDesc"> <el-input v-model="addForm.roleDesc"></el-input> </el-form-item> </el-form> <!--底部按鈕區域--> <span slot="footer" class="dialog-footer"> <el-button @click="addDialogVisible = false">取 消</el-button> <el-button type="primary" @click="addRole">確 定</el-button> </span> </el-dialog>
添加對應js:
<script> export default { data() { return { rolesList: [], // 角色列表數據 addDialogVisible: false, // 控制添加角色對話框是否顯示 // 添加角色的表單數據 addForm: { roleName: '', roleDesc: '' }, // 添加用戶表單的驗證規則對象 addFormRules: { roleName: [ { required: true, message: '請輸入角色名稱', trigger: 'blur' }, { min: 2, max: 10, message: '長度在 2 到 10 個字符', trigger: 'blur' } ], roleDesc: [ { required: true, message: '請輸入角色描述', trigger: 'blur' }, { min: 2, max: 10, message: '長度在 2 到 10 個字符', trigger: 'blur' } ] } } }, created() { this.getRolesList() }, methods: { async getRolesList() { const { data: res } = await this.$http.get('roles') // console.log(res) if (res.meta.status !== 200) { this.$message.error('獲取角色列表失敗') } this.rolesList = res.data }, // 監聽 添加用戶對話框的關閉事件 addDialogClosed() { // 表單內容重置為空 this.$refs.addFormRef.resetFields() // 通過ref引用調用resetFields方法 } } } </script>
效果圖:
實現表單預校驗以及調用api接口完成添加角色的操作
請求路徑:roles,請求方法:post,請求參數:roleName roleDesc
// 點擊按鈕 添加新角色 addRole() { this.$refs.addFormRef.validate(async valid => { // console.log(valid) if (!valid) return // 可以發起添加角色的網絡請求 const { data: res } = await this.$http.post('roles', this.addForm) if (res.meta.status !== 201) return this.$message.error('添加角色失敗') this.$message.success('添加角色成功') // 隱藏添加角色的對話框 this.addDialogVisible = false // 重新發起請求角色列表 this.getRolesList() }) }
效果圖:
5、實現編輯角色功能
因為前面實現過編輯用戶的功能,所以這里就簡單寫了。
給編輯按鈕添加點擊事件:
<el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditDialog(scope.row.id)">編輯</el-button>
添加編輯對話框代碼:
<!--編輯用戶角色的對話框--> <el-dialog title="修改角色信息" :visible.sync="editDialogVisible" width="50%" @close="editDialogClosed" > <!--內容主體區域--> <el-form :model="editForm" :rules="addFormRules" ref="editFormRef" label-width="90px"> <el-form-item label="角色名稱" prop="roleName"> <el-input v-model="editForm.roleName"></el-input> </el-form-item> <el-form-item label="角色描述" prop="roleDesc"> <el-input v-model="editForm.roleDesc"></el-input> </el-form-item> </el-form> <!--底部按鈕區域--> <span slot="footer" class="dialog-footer"> <el-button @click="editDialogVisible = false">取 消</el-button> <el-button type="primary" @click="editUserInfo">確 定</el-button> </span> </el-dialog> <script> export default { data() { return { editDialogVisible: false, // 控制修改角色信息對話框是否顯示 // 修改角色信息的表單數據 editForm: { roleName: '', roleDesc: '' } } }, methods: { // 監聽 修改角色狀態 showEditDialog(id) { this.editDialogVisible = true const { data: res } = await this.$http.get('roles/' + id) if (res.meta.status !== 200) { return this.$message.error('查詢角色信息失敗') } this.editForm = res.data }, // 監聽 修改角色信息對話框的關閉事件 editDialogClosed() { // 表單內容重置為空 this.$refs.editFormRef.resetFields() // 通過ref引用調用resetFields方法 } } } </script>
此時,點擊修改按鈕已經可以彈出對話框了。
添加確定按鈕綁定點擊事件,完成用戶信息的修改
// 點擊按鈕 修改角色信息 editRoleInfo() { this.$refs.editFormRef.validate(async valid => { // console.log(valid) if (!valid) return // 可以發起修改用戶信息的網絡請求 const { data: res } = await this.$http.put( 'roles/' + this.editForm.roleId, this.editForm ) if (res.meta.status !== 200) { return this.$message.error('修改角色信息失敗!') } this.$message.success('修改角色信息成功!') // 關閉對話框 this.editDialogVisible = false // 重新發起請求角色列表 this.getRolesList() }) }
效果圖:
6、實現刪除角色功能
因為前面實現過刪除用戶的功能,所以這里就簡單寫了。
給刪除按鈕添加點擊事件:根據id
<el-button size="mini" type="danger" icon="el-icon-delete" @click="removeUserById(scope.row.id)">刪除</el-button>
removeUserById方法,調用API接口完成刪除角色信息:
刪除角色:請求路徑:roles/:id 請求方法:delete
// 根據ID刪除對應的用戶信息 async removeUserById(id) { console.log(id) // 彈框 詢問用戶是否刪除 const confirmResult = await this.$confirm('此操作將永久刪除該角色, 是否繼續?', '提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' }).catch(err => err) // 如果用戶確認刪除,則返回值為字符串 confirm // 如果用戶取消刪除,則返回值為字符串 cancel // console.log(confirmResult) if (confirmResult !== 'confirm') { return this.$message.info('已取消刪除') } // console.log('確認刪除') const { data: res } = await this.$http.delete('roles/' + id) if (res.meta.status !== 200) { return this.$message.error('刪除角色失敗') } this.$message.success('刪除角色成功') this.getRolesList() }
效果圖:
7、角色權限,通過第一層for循環渲染一級權限
先添加柵格布局,通過作用域插槽實現
<!--展開列--> <el-table-column type="expand"> <template slot-scope="scope"> <el-row> <!--渲染一級權限--> <el-col :span="5"></el-col> <!--渲染二級和三級權限--> <el-col :span="19"></el-col> </el-row> </template> </el-table-column>
然后進行for循環渲染:
<el-row v-for="(item1) in scope.row.children" :key="item1.id"> <!--渲染一級權限--> <el-col :span="5"> <el-tag>{{item1.authName}}</el-tag> </el-col> <!--渲染二級和三級權限--> <el-col :span="19"></el-col> </el-row>
8、美化一級權限的UI
添加樣式,標簽和邊框線:
<style lang="less" scoped> .el-tag{margin:7px;} .bdtop{border-top:1px solid #eee} .bdbottom{border-bottom:1px solid #eee} </style>>
el-row添加樣式動態綁定:class="['bdbottom']",然后添加索引i1,運用三目運算來判斷索引為0的時候加bdtop樣式:
<el-row :class="['bdbottom', i1 == 0 ? 'bdtop' : ' ']" v-for="(item1, i1) in scope.row.children" :key="item1.id">
再添加icon小圖標:
<!--渲染一級權限--> <el-col :span="5"> <el-tag>{{item1.authName}}</el-tag> <i class="el-icon-caret-right"></i> </el-col>
此時效果圖:
9、通過第二層for循環渲染二級權限
在二級和三級的el-col里在添加一個el-row分成2個柵格列,並通過v-for渲染:
<!--渲染二級和三級權限--> <el-col :span="19"> <!--通過for循環嵌套渲染二級權限--> <el-row v-for="(item2) in item1.children" :key="item2.id"> <el-col :span="6"> <el-tag type="success">{{item2.authName}}</el-tag> <i class="el-icon-caret-right"></i> </el-col> <el-col :span="18"></el-col> </el-row> </el-col>
在美化UI:每個二級權限之間也有邊框,添加索引i2進行判斷,索引不為0時添加bdtop:
<!--通過for循環嵌套渲染二級權限--> <el-row :class="[i2 == 0 ? '' : 'bdtop']" v-for="(item2, i2) in item1.children" :key="item2.id"> <el-col :span="6"> <el-tag type="success">{{item2.authName}}</el-tag> <i class="el-icon-caret-right"></i> </el-col>
此時的效果圖:
10、通過第三層for循環渲染三級權限
<el-col :span="18"> <!--通過for循環嵌套渲染三級權限--> <el-tag v-for="(item3) in item2.children" :key="item3.id" type="warning">{{item3.authName}}</el-tag> </el-col>
此時的效果圖:
11、繼續美化角色權限的UI結構
在全局樣式表中指定頁面最少寬度:
html, body, #app {height: 100%; margin: 0; padding: 0;min-width: 1366px;}
添加一級、二級垂直居中對齊樣式:
.vcenter{display: flex;align-items: center}
在給一級和二級的row里添加:
<el-row :class="['bdbottom','vcenter', i1 == 0 ? 'bdtop' : ' ']" v-for="(item1, i1) in scope.row.children" :key="item1.id"> <el-row :class="['vcenter', i2 == 0 ? '' : 'bdtop']" v-for="(item2, i2) in item1.children" :key="item2.id">
12、點擊刪除標簽,彈出確定提示框:
設置closable
屬性可以定義一個標簽是否可移除。
動態編輯標簽可以通過點擊標簽關閉按鈕后觸發的 close
事件來實現。
<!--通過for循環嵌套渲染三級權限--> <el-tag type="warning" closable @close="removeRightById(scope.row, item3.id)" v-for="(item3) in item2.children" :key="item3.id"> {{item3.authName}} </el-tag>
添加removeRightById方法:
// 根據ID刪除對應的權限 async removeRightById(id) { console.log(id) // 彈框 詢問用戶是否刪除 const confirmResult = await this.$confirm( '此操作將永久刪除該權限, 是否繼續?', '提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' } ).catch(err => err) // 如果用戶確認刪除,則返回值為字符串 confirm // 如果用戶取消刪除,則返回值為字符串 cancel // console.log(confirmResult) if (confirmResult !== 'confirm') { return this.$message.info('已取消刪除') } console.log('確認刪除') }
13、完成最終刪除指定權限
還是通過``反引號來拼接地址:
// 根據ID刪除對應的權限 async removeRightById(role, rightId) { console.log(role.id) console.log(rightId) // 彈框 詢問用戶是否刪除 const confirmResult = await this.$confirm( '此操作將永久刪除該權限, 是否繼續?', '提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' } ).catch(err => err) // 如果用戶確認刪除,則返回值為字符串 confirm // 如果用戶取消刪除,則返回值為字符串 cancel // console.log(confirmResult) if (confirmResult !== 'confirm') { return this.$message.info('已取消刪除') } // console.log('確認刪除') const { data: res } = await this.$http.delete( `roles/${role.id}/rights/${rightId}` ) if (res.meta.status !== 200) { return this.$message.error('刪除權限失敗') } this.getRolesList() }
此時點擊權限標簽的刪除,已經可以實現功能。但是有個問題,刪除以后重新發起請求角色列表,整個角色列表刷新,導致打開的權限被閉合了,查看接口文檔,發現刪除角色指定權限的接口,響應數據說明里指出,返回的data, 是當前角色下最新的權限數據,所以可以直接使用這個data渲染權限列表:
// 根據ID刪除對應的權限 async removeRightById(role, rightId) { console.log(role.id) console.log(rightId) // 彈框 詢問用戶是否刪除 const confirmResult = await this.$confirm( '此操作將永久刪除該權限, 是否繼續?', '提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' } ).catch(err => err) // 如果用戶確認刪除,則返回值為字符串 confirm // 如果用戶取消刪除,則返回值為字符串 cancel // console.log(confirmResult) if (confirmResult !== 'confirm') { return this.$message.info('已取消刪除') } // console.log('確認刪除') const { data: res } = await this.$http.delete( `roles/${role.id}/rights/${rightId}` ) console.log(res) if (res.meta.status !== 200) { return this.$message.error('刪除權限失敗') } // this.getRolesList() role.children = res.data }
ok,現在可以刪除后,還是權限打開狀態,只有被刪除的標簽消失。
下面就添加二級刪除權限:
<!--渲染一級權限--> <el-tag closable @close="removeRightById(scope.row,item1.id)">{{item1.authName}}</el-tag> <!--通過for循環嵌套渲染二級權限--> <el-row :class="['vcenter', i2 == 0 ? '' : 'bdtop']" v-for="(item2, i2) in item1.children" :key="item2.id">
現在點擊一級、二級、三級都可以進行刪除操作了。
效果圖: