学习笔记
props写在el-table当中是什么用途的? 5W3H 为什么这么写?怎么来的?这个里面还包含什么?你要把概念去理解清楚的。为什么用prop不用别的呢?
代码是你写的是什么就是什么,就是这样子。把知识去看,用自己的话能讲出来最重要了。
厉害的学代码的人,前端笔记很多可以看。
例如
<!-- 索引列 -->
<el-table-column type="index" label="#"></el-table-column>
<el-table-column label="角色名称" prop="roleName"></el-table-column>
<el-table-column label="角色描述" prop="roleDesc"></el-table-column>
<el-table-column label="操作" width="300px">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini" >编辑</el-button>
<el-button type="danger" icon="el-icon-delete" size="mini" >删除</el-button>
————————————————
版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649

项目代码
router.js
1 import Vue from 'vue' 2 import Router from 'vue-router' 3 import Login from './components/Login.vue' 4 import Home from './components/Home.vue' 5 import Welcome from './components/Welcome.vue' 6 import Users from './components/user/Users.vue' 7 import Right from './components/power/Right.vue' 8 import Roles from './components/power/Roles.vue' 9 Vue.use(Router) 10 11 const router = new Router({ 12 routes: [{ 13 path: '/', 14 redirect: '/login' 15 }, 16 { 17 path: '/login', 18 component: Login 19 }, 20 { 21 path: '/home', 22 component: Home, 23 redirect: '/welcome', 24 children: [{ 25 path: '/welcome', 26 component: Welcome 27 }, { 28 path: '/users', 29 component: Users 30 }, 31 { 32 path: '/rights', 33 component: Right 34 }, 35 { 36 path: '/roles', 37 component: Roles 38 }] 39 } 40 ] 41 }); 42 //挂载路由导航守卫 43 router.beforeEach((to, from, next) => { 44 if (to.path === '/login') return next(); 45 //获取token 46 const tokenStr = window.sessionStorage.getItem('token') 47 if (!tokenStr) return next('/login') 48 next(); 49 }) 50 51 export default router 52 ———————————————— 53 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 54 原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649
login.vue
1 <template> 2 3 <div class="login_container"> 4 <div class="login_box"> 5 <div class="avatar_box"> 6 <img src="../assets/logo.png"> 7 </div> 8 <!-- 表单区域--> 9 <el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form"> 10 <!-- 登录区域--> 11 <el-form-item prop="username"> 12 <el-input v-model="loginForm.username" prefix-icon="iconfont icon-user"></el-input> 13 </el-form-item> 14 <el-form-item prop="password"> 15 <el-input type="password" v-model="loginForm.password" prefix-icon="iconfont icon-3702mima"></el-input> 16 </el-form-item> 17 <el-form-item class="btns"> 18 <el-button type="primary" @click="login">登录</el-button> 19 <el-button type="info" @click="resetLoginForm">重置</el-button> 20 </el-form-item> 21 </el-form> 22 </div> 23 </div> 24 25 </template> 26 27 <script> 28 export default{ 29 data(){ 30 return{ 31 //这是登录表单的数据 32 loginForm:{ 33 username:'geyao', 34 password:'12345678' 35 }, 36 // 表单验证 37 loginFormRules: { 38 username: [ 39 { required: true, message: '请输入用户名', trigger: 'blur' }, 40 { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' } 41 ], 42 password: [ 43 { required: true, message: '请输入用户密码', trigger: 'blur' }, 44 { min: 6, max: 18, message: '长度在 6 到 18 个字符', trigger: 'blur' } 45 ] 46 } 47 } 48 }, 49 methods:{ 50 resetLoginForm(){ 51 // console.log(this) 52 this.$refs.loginFormRef.resetFields(); 53 }, 54 login(){ 55 this.$refs.loginFormRef.validate(async valid =>{ 56 if(!valid) return; 57 const {data:res}=await this.$http.post('login',this.loginForm); 58 if(res.meta.status!==200) return this.$message.error('登录失败'); 59 this.$message.success('登录成功'); 60 // 1、将登陆成功之后的token, 保存到客户端的sessionStorage中; 61 // 1.1 项目中出现了登录之外的其他API接口,必须在登陆之后才能访问 62 // 1.2 token 只应在当前网站打开期间生效,所以将token保存在 63 window.sessionStorage.setItem('token', res.data.token) 64 // 2、通过编程式导航跳转到后台主页, 路由地址为:/home 65 this.$router.push('/home') 66 }); 67 } 68 } 69 } 70 </script> 71 72 <style lang="less" scoped> 73 .login_container { 74 background-color: #2b4b6b; 75 height: 100%; 76 } 77 .login_box { 78 width: 450px; 79 height: 360px; 80 background-color: #fff; 81 border-radius: 3px; 82 position: absolute; 83 left: 50%; 84 top: 50%; 85 -webkit-transform: translate(-50%, -50%); 86 background-color: #fff; 87 } 88 .avatar_box { 89 width: 130px; 90 height: 130px; 91 border: 1px solid #eee; 92 border-radius: 50%; 93 padding: 10px; 94 box-shadow: 0 0 10px #ddd; 95 position: absolute; 96 left: 50%; 97 transform: translate(-50%, -50%); 98 background-color: #fff; 99 img { 100 width: 100%; 101 height: 100%; 102 border-radius: 50%; 103 background-color: #eee; 104 } 105 } 106 .login_form { 107 position: absolute; 108 bottom: 60px; 109 width: 100%; 110 padding: 0 20px; 111 box-sizing: border-box; 112 } 113 .btns { 114 display: flex; 115 justify-content: center; 116 } 117 </style> 118 ———————————————— 119 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 120 原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649
main.js
1 import Vue from 'vue' 2 import App from './App.vue' 3 import router from './router' 4 import './plugins/element.js' 5 //导入字体图标 6 import './assets/fonts/iconfont.css' 7 Vue.config.productionTip = false 8 //导入全局样式 9 import './assets/css/global.css' 10 11 import axios from 'axios' 12 Vue.prototype.$http=axios 13 axios.defaults.baseURL="http://127.0.0.1:8888/api/private/v1/" 14 // 请求在到达服务器之前,先会调用use中的这个回调函数来添加请求头信息 15 axios.interceptors.request.use(config => { 16 17 // console.log(config) 18 // 为请求头对象,添加token验证的Authorization字段 19 config.headers.Authorization = window.sessionStorage.getItem('token') 20 // 在最后必须 return config 21 return config 22 }) 23 Vue.config.productionTip=false; 24 new Vue({ 25 router, 26 render: h => h(App) 27 }).$mount('#app') 28 ———————————————— 29 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 30 原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649
global.css
1 /* 全局样式 */ 2 html, 3 body, 4 #app { 5 height: 100%; 6 margin: 0; 7 padding: 0; 8 9 } 10 11 .el-breadcrumb { 12 margin-bottom: 15px; 13 font-size: 12px; 14 } 15 16 .el-card { 17 box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15) !important; 18 } 19 20 .el-table { 21 margin-top: 15px; 22 font-size: 12px; 23 } 24 25 .el-pagination { 26 margin-top: 15px; 27 } 28 ———————————————— 29 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 30 原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649
element.js
1 import Vue from 'vue' 2 3 //弹框提示 4 import { 5 Message, 6 Button, 7 Form, 8 FormItem, 9 Input, 10 Container, 11 Header, 12 Aside, 13 Main, 14 Menu, 15 Submenu, 16 MenuItemGroup, 17 MenuItem, 18 Breadcrumb, 19 BreadcrumbItem, 20 Card, 21 Row, 22 Col, 23 Table, 24 TableColumn, 25 Switch, 26 Tooltip, 27 Pagination, 28 Dialog, 29 MessageBox, 30 Tag, 31 Tree 32 } from 'element-ui' 33 Vue.use(Button) 34 Vue.use(Form) 35 Vue.use(FormItem) 36 Vue.use(Input) 37 Vue.use(Container) 38 Vue.use(Header) 39 Vue.use(Aside) 40 Vue.use(Main) 41 Vue.use(Menu) 42 Vue.use(Submenu) 43 Vue.use(MenuItemGroup) 44 Vue.use(MenuItem) 45 Vue.use(Breadcrumb) 46 Vue.use(BreadcrumbItem) 47 Vue.use(Card) 48 Vue.use(Row) 49 Vue.use(Col) 50 Vue.use(Table) 51 Vue.use(TableColumn) 52 Vue.use(Switch) 53 Vue.use(Tooltip) 54 Vue.use(Pagination) 55 Vue.use(Dialog) 56 Vue.use(Tag) 57 Vue.use(Tree) 58 Vue.prototype.$confirm=MessageBox 59 Vue.prototype.$message = Message 60 ———————————————— 61 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 62 原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649
Home.vue
1 import Vue from 'vue' 2 import Router from 'vue-router' 3 import Login from './components/Login.vue' 4 import Home from './components/Home.vue' 5 import Welcome from './components/Welcome.vue' 6 import Users from './components/user/Users.vue' 7 Vue.use(Router) 8 9 const router = new Router({ 10 routes: [{ 11 path: '/', 12 redirect: '/login' 13 }, 14 { 15 path: '/login', 16 component: Login 17 }, 18 { 19 path: '/home', 20 component: Home, 21 redirect: '/welcome', 22 children: [{ 23 path: '/welcome', 24 component: Welcome 25 }, { 26 path: '/users', 27 component: Users 28 }] 29 } 30 ] 31 }); 32 //挂载路由导航守卫 33 router.beforeEach((to, from, next) => { 34 if (to.path === '/login') return next(); 35 //获取token 36 const tokenStr = window.sessionStorage.getItem('token') 37 if (!tokenStr) return next('/login') 38 next(); 39 }) 40 41 export default router 42 ———————————————— 43 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 44 原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649
类名的样式
.prettierrc
1 { 2 "semi":false, 3 "singleQuote":true 4 }
eslintrc.js
1 module.exports = { 2 root: true, 3 env: { 4 node: true 5 }, 6 extends: [ 7 'plugin:vue/essential', 8 '@vue/standard' 9 ], 10 parserOptions: { 11 parser: 'babel-eslint' 12 }, 13 rules: { 14 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 15 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 16 'space-before-function-paren':0 17 18 } 19 } 20 21 ———————————————— 22 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 23 原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649
welcome.vue
1 <template> 2 <div> 3 <h3>欢迎</h3> 4 </div> 5 </template>
Users.vue
<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 :gutter="20">
<el-col :span="7">
<el-input placeholder="请输入内容" v-model="queryInfo.query" clearable @clear="getUserList">
<el-button slot="append" icon="el-icon-search" @click="getUserList"></el-button>
</el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="addDialogVisible=true">添加用户</el-button>
</el-col>
</el-row>
<el-table border stripe :data="userlist">
<el-table-column type="index" label="#"></el-table-column>
<el-table-column prop="username" label="姓名"></el-table-column>
<el-table-column prop="email" label="邮箱"></el-table-column>
<el-table-column prop="mobile" label="电话"></el-table-column>
<el-table-column prop="role_name" label="角色"></el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-switch v-model="scope.row.mg_state" @change="userStateChanged(scope.row)"></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="180px">
<template slot-scope="scope">
<el-button
type="primary"
icon="el-icon-edit"
size="mini"
circle
@click="showEditDialog(scope.row.id)"
></el-button>
<el-button type="danger" icon="el-icon-delete" size="mini" circle
@click="removeUserById(scope.row.id)"></el-button>
<el-tooltip
class="item"
effect="dark"
content="角色分配"
:enterable="false"
placement="top"
>
<el-button type="warning" icon="el-icon-setting" size="mini" circle
@click="showSetRole(scope.row)"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="queryInfo.pagenum"
:page-sizes="[2, 5, 10, 15]"
:page-size="queryInfo.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</el-card>
<!-- 添加用户的对话框 -->
<el-dialog title="添加用户" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed">
<!-- 内容主体 -->
<el-form :model="addForm" ref="addFormRef" :rules="addFormRules" label-width="70px">
<el-form-item label="用户名" prop="username">
<el-input v-model="addForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="addForm.password"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="addForm.email"></el-input>
</el-form-item>
<el-form-item label="手机" prop="mobile">
<el-input v-model="addForm.mobile"></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="addUser">确 定</el-button>
</span>
</el-dialog>
<!-- 修改用户的对话框 -->
<el-dialog
title="修改用户信息"
:visible.sync="editDialogVisible"
width="50%"
@close="editDialogClosed"
>
<el-form :model="editForm" ref="editUserFormRef" :rules="editFormRules" label-width="70px">
<el-form-item label="用户名">
<el-input v-model="editForm.username" disabled></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="editForm.email"></el-input>
</el-form-item>
<el-form-item label="手机" prop="mobile">
<el-input v-model="editForm.mobile"></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>
<!-- 分配角色对话框 -->
<el-dialog title="分配角色" :visible.sync="setRoleDialogVisible" width="50%" >
<div>
<p>当前用户:{{userInfo.username}}</p>
<p>当前角色:{{userInfo.role_name}}</p>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="setRoleDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="setRoleDialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<style scoped="less" scoped>
</style>
<script>
export default {
data() {
// 自定义邮箱规则
var checkEmail = (rule, value, callback) => {
const regEmail = /^\w+@\w+(\.\w+)+$/
if (regEmail.test(value)) {
// 合法邮箱
return callback()
}
callback(new Error('请输入合法邮箱'))
}
// 自定义手机号规则
var checkMobile = (rule, value, callback) => {
const regMobile = /^1[34578]\d{9}$/
if (regMobile.test(value)) {
return callback()
}
// 返回一个错误提示
callback(new Error('请输入合法的手机号码'))
}
return {
queryInfo: {
query: '',
pagenum: 1,
pagesize: 2,
},
userlist: [],
total: 0,
addDialogVisible: false,
addForm: {
username: '',
password: '',
email: '',
mobile: '',
},
addFormRules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{
min: 2,
max: 10,
message: '用户名的长度在2~10个字',
trigger: 'blur',
},
],
password: [
{ required: true, message: '请输入用户密码', trigger: 'blur' },
{
min: 6,
max: 18,
message: '用户密码的长度在6~18个字',
trigger: 'blur',
},
],
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ validator: checkEmail, trigger: 'blur' },
],
mobile: [
{ required: true, message: '请输入手机号码', trigger: 'blur' },
{ validator: checkMobile, trigger: 'blur' },
],
},
editFormRules: {
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ validator: checkEmail, trigger: 'blur' },
],
mobile: [
{ required: true, message: '请输入手机号码', trigger: 'blur' },
{ validator: checkMobile, trigger: 'blur' },
],
},
editDialogVisible: false,
editForm: {},
setRoleDialogVisible:false,
userInfo:{},
rolelist:[]
}
},
created() {
this.getUserList()
},
methods: {
async getUserList() {
const { data: res } = await this.$http.get('users', {
params: this.queryInfo,
})
if (res.meta.status !== 200) {
return this.$message.error('获取用户列表失败!')
}
this.userlist = res.data.users
this.total = res.data.total
console.log(res)
},
// 监听修改用户对话框的关闭事件
editDialogClosed() {
this.$refs.editUserFormRef.resetFields()
},
// 监听 pagesize改变的事件
handleSizeChange(newSize) {
// console.log(newSize)
this.queryInfo.pagesize = newSize
this.getUserList()
},
// 监听 页码值 改变事件
handleCurrentChange(newSize) {
// console.log(newSize)
this.queryInfo.pagenum = newSize
this.getUserList()
},
async userStateChanged(userInfo) {
// console.log(userInfo)
const { data: res } = await this.$http.put(
`users/${userInfo.id}/state/${userInfo.mg_state}`
)
if (res.meta.status !== 200) {
userInfo.mg_state = !userInfo.mg_state
return this.$message.error('更新用户状态失败')
}
this.$message.success('更新用户状态成功!')
},
// 监听 添加用户对话框的关闭事件
addDialogClosed() {
this.$refs.addFormRef.resetFields()
},
editUserInfo() {
this.$refs.editUserFormRef.validate(async (valid) => {
if (!valid) return
const { data: res } = await this.$http.put(
'users/' + this.editForm.id,
{
email: this.editForm.email,
mobile: this.editForm.mobile,
}
)
if (res.meta.status !== 200) {
this.$message.error('更新用户信息失败!')
}
// 隐藏添加用户对话框
this.editDialogVisible = false
this.$message.success('更新用户信息成功!')
this.getUserList()
})
},
// 编辑用户信息
async showEditDialog(id) {
const { data: res } = await this.$http.get('users/' + id)
if (res.meta.status !== 200) {
return this.$message.error('查询用户信息失败!')
}
this.editForm = res.data
this.editDialogVisible = true
},
// 添加用户
addUser() {
// 提交请求前,表单预验证
this.$refs.addFormRef.validate(async (valid) => {
// console.log(valid)
// 表单预校验失败
if (!valid) return
const { data: res } = await this.$http.post('users', this.addForm)
if (res.meta.status !== 201) {
this.$message.error('添加用户失败!')
}
this.$message.success('添加用户成功!')
// 隐藏添加用户对话框
this.addDialogVisible = false
this.getUserList()
})
},
// 删除用户
async removeUserById (id) {
const confirmResult = await this.$confirm(
'此操作将永久删除该用户, 是否继续?',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).catch(err => err)
// 点击确定 返回值为:confirm
// 点击取消 返回值为: cancel
if (confirmResult !== 'confirm') {
return this.$message.info('已取消删除')
}
const { data: res } = await this.$http.delete('users/' + id)
if (res.meta.status !== 200) return this.$message.error('删除用户失败!')
this.$message.success('删除用户成功!')
this.getUserList()
},async showSetRole (userInfo) {
this.userInfo = userInfo
// 展示对话框之前,获取所有角色列表
const { data: res } = await this.$http.get('roles')
if (res.meta.status !== 200) {
return this.$message.error('获取角色列表失败!')
}
this.rolelist = res.data
this.setRoleDialogVisible = true
},
},
}
</script>
————————————————
版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649
Right.vue
1 <template> 2 <div> 3 <!-- 面包屑导航区 --> 4 <el-breadcrumb separator-class="el-icon-arrow-right"> 5 <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item> 6 <el-breadcrumb-item>权限管理</el-breadcrumb-item> 7 <el-breadcrumb-item>权限列表</el-breadcrumb-item> 8 </el-breadcrumb> 9 <el-card> 10 <el-table :data="rightsList"> 11 <el-table-column type="index" label="#"></el-table-column> 12 <el-table-column label="权限名称" prop="authName"></el-table-column> 13 <el-table-column label="路径" prop="path"></el-table-column> 14 <el-table-column label="权限等级" prop="level"> 15 <template slot-scope="scope"> 16 <el-tag v-if="scope.row.level === '0'">一级</el-tag> 17 <el-tag type="success" v-else-if="scope.row.level === '1'">二级</el-tag> 18 <el-tag type="danger" v-else>三级</el-tag> 19 </template> 20 </el-table-column> 21 </el-table> 22 </el-card> 23 </div> 24 </template> 25 26 <style lang="less" scoped> 27 </style> 28 29 <script> 30 export default { 31 data(){ 32 return{ 33 //权限列表 34 rightsList:[] 35 } 36 }, 37 created(){ 38 this.getRightList() 39 }, 40 methods:{ 41 //获取权限列表 42 async getRightList(){ 43 const {data:res}= await this.$http.get('rights/list') 44 if(res.meta.status!==200){ 45 return this.$message.console.error("获取权限列表失败"); 46 } 47 this.rightsList=res.data 48 } 49 } 50 } 51 </script> 52 53 ———————————————— 54 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 55 原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649
1 <template> 2 <div> 3 <!-- 面包屑导航区 --> 4 <el-breadcrumb separator-class="el-icon-arrow-right"> 5 <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item> 6 <el-breadcrumb-item>权限管理</el-breadcrumb-item> 7 <el-breadcrumb-item>角色列表</el-breadcrumb-item> 8 </el-breadcrumb> 9 10 <el-card> 11 <el-row> 12 <el-col> 13 <el-button type="primary">添加角色</el-button> 14 </el-col> 15 </el-row> 16 <el-table :data="roleslist" border stripe> 17 <el-table-column type="expand"> 18 <template slot-scope="scope"> 19 <el-row 20 :class="['bdbottom', i1 === 0 ? 'bdtop' : '', 'vcenter']" 21 v-for="(item1, i1) in scope.row.children" 22 :key="item1.id"> 23 <!-- 一级权限 --> 24 <el-col :span="5"> 25 <el-tag closable @close="removeRightById(scope.row, item1.id)">{{ item1.authName}}</el-tag> 26 <i class="el-icon-caret-right"></i> 27 </el-col> 28 <el-col :span="19"> 29 <el-row :class="[i2 === 0 ? '' : 'bdtop','vcenter']" 30 v-for="(item2, i2) in item1.children" 31 :key="item2.id"> 32 <el-col :span="6 "> 33 <el-tag 34 type="success" 35 closable 36 @close="removeRightById(scope.row, item2.id)" 37 >{{ item2.authName }}</el-tag> 38 <i class="el-icon-caret-right"></i> 39 </el-col> 40 <el-col :span="18"> 41 <el-tag 42 type="warning" 43 v-for="(item3) in item2.children" 44 :key="item3.id" 45 closable 46 @close="removeRightById(scope.row,item3.id)" 47 48 >{{ item3.authName}}</el-tag> 49 50 </el-col> 51 </el-row> 52 </el-col> 53 </el-row> 54 <!--<pre> 55 {{scope.row}} 56 </pre>--> 57 </template> 58 </el-table-column> 59 <!-- 索引列 --> 60 <el-table-column type="index" label="#"></el-table-column> 61 <el-table-column label="角色名称" prop="roleName"></el-table-column> 62 <el-table-column label="角色描述" prop="roleDesc"></el-table-column> 63 <el-table-column label="操作" width="300px"> 64 <template slot-scope="scope"> 65 <el-button type="primary" icon="el-icon-edit" size="mini" >编辑</el-button> 66 <el-button type="danger" icon="el-icon-delete" size="mini" >删除</el-button> 67 <el-button 68 type="warning" 69 icon="el-icon-setting" 70 size="mini" 71 @click="showSetRightDialog(scope.row)" 72 >分配权限</el-button> 73 </template> 74 </el-table-column> 75 </el-table> 76 </el-card> 77 <!-- 分配权限 --> 78 <el-dialog 79 title="分配权限" 80 :visible.sync="setRightDialogVisible" 81 width="50%" 82 @close="setRightDialogClosede" 83 > 84 <el-tree 85 :data="rightslist" 86 :props="treeProps" 87 ref="treeRef" 88 show-checkbox 89 node-key="id" 90 default-expand-all 91 :default-checked-keys="defKeys" 92 ></el-tree> 93 <span slot="footer" class="dialog-footer"> 94 <el-button @click="setRightDialogVisible = false">取 消</el-button> 95 <el-button type="primary" @click="allotRights">确 定</el-button> 96 </span> 97 </el-dialog> 98 </div> 99 </template> 100 101 <script> 102 export default { 103 data(){ 104 return{ 105 //所有角色列表数据 106 roleslist:[], 107 setRightDialogVisible:false, 108 rightslist:[], 109 treeProps:{ 110 label:'authName', 111 children:'children' 112 }, 113 defKeys:[], 114 roleId:'' 115 } 116 }, 117 created(){ 118 this.getRolesList() 119 }, 120 methods:{ 121 async getRolesList (role,rightId) { 122 const { data: res } = await this.$http.get('roles') 123 if (res.meta.status !== 200) { 124 return this.$message.error('获取角色列表失败!') 125 } 126 this.roleslist = res.data 127 console.log(this.roleslist) 128 }, 129 async removeRightById () { 130 // 弹框提示 删除 131 const confirmResult = await this.$confirm( 132 '此操作将永久删除该权限, 是否继续?', 133 '提示', 134 { 135 confirmButtonText: '确定', 136 cancelButtonText: '取消', 137 type: 'warning' 138 } 139 ).catch(err => err) 140 // 点击确定 返回值为:confirm 141 // 点击取消 返回值为: cancel 142 if (confirmResult !== 'confirm') { 143 return this.$message.info('已取消权限删除') 144 } 145 const { data: res } = await this.$http.delete( 146 `roles/${role.id}/rights/${rightId}` 147 ) 148 if (res.meta.status !== 200) { 149 return this.$message.error('删除权限失败!') 150 } 151 this.roleslist = res.data 152 // 不建议使用 153 //this.getRolesList() 154 role.children=res.data 155 },async showSetRightDialog(role){ 156 this.roleId=role.id 157 // 获取角色的所有权限 158 const { data: res } = await this.$http.get('rights/tree') 159 if (res.meta.status !== 200) { 160 return this.$message.error('获取权限数据失败!') 161 } 162 // 获取权限树 163 this.rightslist = res.data 164 // console.log(res) 165 // 递归获取三级节点的id 166 //this.getLeafkeys(role, this.defKeys) 167 this.getLeafkeys(role,this.defKeys) 168 this.setRightDialogVisible = true 169 console.log(this.rightslist) 170 },// 通过递归 获取角色下三级权限的 id, 并保存到defKeys数组 171 getLeafkeys (node, arr) { 172 // 没有children属性,则是三级节点 173 if (!node.children) { 174 return arr.push(node.id) 175 } 176 node.children.forEach(item => this.getLeafkeys(item, arr)) 177 }, 178 // 权限对话框关闭事件 179 setRightDialogClosed () { 180 this.rightslist = [] 181 }, 182 // 添加角色对话框的关闭 183 addRoleDialogClosed () { 184 this.$refs.addRoleFormRef.resetFields() 185 },setRightDialogClosede(){ 186 this.defKeys=[]; 187 }, 188 // 分配权限 189 async allotRights (roleId) { 190 // 获得当前选中和半选中的Id 191 const keys = [ 192 ...this.$refs.treeRef.getCheckedKeys(), 193 ...this.$refs.treeRef.getHalfCheckedKeys() 194 ] 195 // join() 方法用于把数组中的所有元素放入一个字符串 196 const idStr = keys.join(',') 197 const { data: res } = await this.$http.post(`roles/${this.roleId}/rights`, { rids: idStr }) 198 if (res.meta.status !== 200) { return this.$message.error('分配权限失败!') } 199 this.$message.success('分配权限成功!') 200 this.getRolesList() 201 this.setRightDialogVisible = false 202 } 203 204 205 } 206 } 207 </script> 208 209 <style lang="less" scoped> 210 .el-tag { 211 margin: 7px; 212 } 213 214 .bdtop { 215 border-top: 1px solid #eee; 216 } 217 .bdbottom { 218 border-bottom: 1px solid #eee; 219 } 220 .vcenter { 221 display: flex; 222 align-items: center; 223 } 224 </style> 225 226 ———————————————— 227 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 228 原文链接:https://blog.csdn.net/weixin_43392489/article/details/107797649

浙公网安备 33010602011771号