第2章 用户管理
2.1 路由及组件
/src/components/home/home.vue
<el-menu-item index="users">
<i class="el-icon-menu"></i>
用户列表
</el-menu-item>
src/router/index.js
import Users from '@/components/users/users'
……
children:[
{path:'index',name:'index',component:Index},
{path:'users',name:'users',component:Users}
]
src/components/users/users.vue
<template>
<div>展示用户列表表格</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
2.2 面包屑导航及搜索框
src/components/users/users.vue
Card 卡片
Breadcrumb 面包屑
Input 输入框
Button 按钮
<template>
<div>
<!-- 面包鞋 -->
<el-card>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>用户管理</el-breadcrumb-item>
<el-breadcrumb-item>用户列表</el-breadcrumb-item>
</el-breadcrumb>
</el-card>
</div>
</template>
……
</el-card>
<el-row>
<el-col :span="6" class="sou">
<el-input placeholder="请输入内容" v-model="input5" class="input-with-select">
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
</el-col>
<el-col :span="1" class="sou">
<el-button type="success" plain>添加用户</el-button>
</el-col>
</el-row>
</div>
……
<script>
export default {
data(){
// 不想看到报错
return{input5:''}
}
};
</script>
<style>
.sou{
line-height:30px
}
</style>
2.3 展示用户列表
2.3.4 组件展示
src/components/users/users.vue
Table 表格->自定义索引
<!-- 表格 自定义索引 -->
<el-table
:data="tableData"
style="width: 100% ;">
<el-table-column
type="index"
:index="indexMethod">
</el-table-column>
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
input5:'',
tableData: [
{
date: "2016-05-03",
name: "王小虎"
}
]
};
}
};
</script>
<style>
.sou {
line-height: 30px;
}
.el-main{
line-height:30px;
}
</style>
2.3.5 获取数据
出登录接口,其他接口发送http请求,必须携带token值
Axios : https://www.kancloud.cn/yunye/axios/234845 ---> 请求配置
data() {
return {
input5:'',// 不想看到报错
// 设置页码及条数
pagenum:1,
pagesize:5,
tableData: []
};
},
// 利用钩子函数,获取数据
mounted() {
// 获取token
let token = window.localStorage.getItem('token');
// 通过配置选项发送请求
// 携带token
this.$myHttp({
// 设置链接地址 es6新语法
url:`users?pagenum=${this.pagenum}&pagesize=${this.pagesize}`,
method:'get',
// 配置token
headers: {'Authorization': token}
}).then(res=>{
// 修改数据 展示页面
this.tableData = res.data.data.users;
})
},
修改组件参数,展示数据:
<el-table-column prop="username" label="姓名" > </el-table-column>
2.3.6 操作按钮
Button 按钮
Table 表格->自定义列模板
<el-table-column label="操作" width="210">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini" plain></el-button>
<el-button type="primary" icon="el-icon-check" size="mini" plain></el-button>
<el-button type="primary" icon="el-icon-delete" size="mini" plain></el-button>
</template>
</el-table-column>
表格中加入按钮等元素时,需要使用 template
进行包裹:
<el-table-column label="用户状态" width="210">
<template slot-scope="scope">
<el-switch
v-model="value2"
active-color="#13ce66"
inactive-color="#ff4949">
</el-switch>
</template>
</el-table-column>
2.3.7 状态显示
而在template
标签中有一个 slot-scope="scope"
属性,scope
的值就是本列中所有数据的值,参考: Table 表格->固定列
<el-table-column label="用户状态" width="210">
<template slot-scope="scope">
<!-- 利用scope 中的值,争取显示用户状态 -->
<el-switch v-model="scope.row.mg_state" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
<!-- 测试事件,查看 scope 数据 -->
<el-button type="primary" size="mini" @click="showScope(scope)">显示scope</el-button>
</template>
</el-table-column>
methods:{
// 测试 方法 显示scope
showScope(scope){
console.log(scope);
}
},
2.3.8 分页展示
Pagination 分页->附加功能
<!-- 分页 -->
<!--
current-page 当前页码数
page-sizes 显示条数选项
page-size 当前每页条数
-->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pagenum"
:page-sizes="[2, 20, 40]"
:page-size="pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</template>
……
<script>
……
data() {
return {
input5:'',// 不想看到报错
pagenum:1, //设置页码
pagesize:2, // 设置页条数
total:0, //显示总条数
tableData: []
};
},
……
……
// 获取总条数 修改数据展示
this.total = res.data.data.total;
但点击页码时,会触发 size-change
事件
<script>
export default {
data() {
return {
input5: "", // 不想看到报错
pagenum: 1, //设置页码
pagesize: 2, // 设置页条数
total: 0, //显示总条数
tableData: []
};
},
methods: {
// 获取用户数据
getUserData() {
// 获取token
let token = window.localStorage.getItem("token");
// 通过配置选项发送请求
// 携带token
this.$myHttp({
// 设置链接地址 es6新语法
url: `users?pagenum=${this.pagenum}&pagesize=${this.pagesize}`,
method: "get",
// 配置token
headers: { Authorization: token }
}).then(res => {
// 修改数据 展示页面
this.tableData = res.data.data.users;
// 获取总条数 修改数据展示
this.total = res.data.data.total;
});
},
// 点击页码触发
handleCurrentChange(pages) {
// console.log(pages);
// 修改data数据,重新发送请求
this.pagenum = pages;
this.getUserData();
},
// 改变显示条数时触发
handleSizeChange(numbers){
this.pagesize = numbers;
this.getUserData();
}
},
// 利用钩子函数,获取数据
mounted() {
this.getUserData();
}
};
</script>
2.4 模糊搜索
请求地址中加入 query 请求参数,获取条件结果
<el-input placeholder="请输入内容" v-model="search" class="input-with-select">
<el-button slot="append"
@click="searchUsers"
icon="el-icon-search"></el-button>
</el-input>
……
<script>
data() {
return {
search: "", // 搜索关键字
};
},
// 请求地址中加入关键字
url: `users?pagenum=${this.pagenum}&pagesize=${this.pagesize}&query=${this.search}`,
// 点击搜索事件
searchUsers(){
this.getUserData();
}
</script>
2.5 切换用户状态
<!-- 利用scope 中的值,争取显示用户状态 -->
<!-- 组件自带change事件 -->
<el-switch v-model="scope.row.mg_state" @change="change(scope)" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
// Switch 开关 组件自带事件
change(scope){
// 接受本条全部信息
// console.log(scope)
let id = scope.row.id; // 获取id
var state = scope.row.mg_state; // 获取修改后的状态
// 请求接口
this.$myHttp.put(`users/${id}/state/${state}`)
.then(res=>{
// 修改失败,将状态改为原始值
if(!res.data.data){
this.tableData[scope.$index].mg_state = !state;
this.$message.error("修改失败");
}
})
}
修改失败是因为没有token:
// Switch 开关 组件自带事件
change(scope){
// 接受本条全部信息
// console.log(scope)
let id = scope.row.id; // 获取id
var state = scope.row.mg_state; // 获取修改后的状态
// 请求接口
// 需要使用配置参数请求,设置token
this.$myHttp({
url:`users/${id}/state/${state}`,
method:'put',
headers: { Authorization: window.localStorage.getItem("token") }
})
.then(res=>{
// 修改失败,将状态改为原始值
if(!res.data.data){
this.tableData[scope.$index].mg_state = !state;
this.$message.error("修改失败");
}
})
}
2.6 删除用户
MessageBox 弹框->确认消息
// 组件中绑定点击按钮
<el-button type="primary" icon="el-icon-delete" size="mini" @click="deleteUser(scope.row.id)" plain></el-button>
// 删除用户
deleteUser(id) {
// this.$myHttp({
// url: `users/${id}`,
// method: "delete",
// headers: { Authorization: window.localStorage.getItem("token") }
// }).then(res => {
// this.getUserData();
// this.$message({
// message: "删除成功",
// type: "success"
// });
// });
this.$confirm("此操作将永久删除该用户, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$myHttp({
url: `users/${id}`,
method: "delete",
headers: { Authorization: window.localStorage.getItem("token") }
}).then(res => {
this.getUserData();
this.$message({
message: "删除成功",
type: "success"
});
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除"
});
});
}
2.7 添加用户
Dialog对话框->自定义内容->打开嵌套表单的 Dialog
Form 表单
表单弹窗:
<el-col :span="1" class="sou">
<!-- 绑定按钮点击事件 直接将 dialogFormVisible值设置为true显示窗口 -->
<el-button type="success" @click="dialogFormVisible = true" >添加用户</el-button>
<!--
:visible.sync属性 控制窗口显示隐藏
-->
<el-dialog title="收货地址" :visible.sync="dialogFormVisible">
<el-form :model="form">
<el-form-item label="活动名称" :label-width="formLabelWidth">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<!-- 点击取消或确定修改dialogFormVisible=false关闭窗口 -->
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
</div>
</el-dialog>
</el-col>
</el-row>
修改表单
<el-col :span="1" class="sou">
<!-- 绑定按钮点击事件 直接将 dialogFormVisible值设置为true显示窗口 -->
<el-button type="success" @click="dialogFormVisible = true" >添加用户</el-button>
<!--
:visible.sync属性 控制窗口显示隐藏
-->
<el-dialog title="添加用户" :visible.sync="dialogFormVisible">
<el-form :model="form">
<el-form-item label="姓名" label-width="90px">
<el-input v-model="form.username" ></el-input>
</el-form-item>
<el-form-item label="密码" label-width="90px">
<el-input v-model="form.password" ></el-input>
</el-form-item>
<el-form-item label="邮箱" label-width="90px">
<el-input v-model="form.email" ></el-input>
</el-form-item>
<el-form-item label="电话" label-width="90px">
<el-input v-model="form.mobile" ></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<!-- 点击取消或确定修改dialogFormVisible=false关闭窗口 -->
<el-button @click="dialogFormVisible = false">取 消</el-button>
<!-- 修改点击事件,在数据入库成功后关闭窗口 -->
<el-button type="primary" @click="addUser">确 定</el-button>
</div>
</el-dialog>
</el-col>
添加数据及方法
data() {
return {
dialogFormVisible: false,
form: {
username: '',
password:'',
email:'',
mobile:''
},
……
methods 方法
// 添加用户
addUser(){
this.$myHttp({
url:'users',
method:'post',
// post数据提交
data:this.form,
headers: { Authorization: window.localStorage.getItem("token") }
}).then(res=>{
let {data} = res;
if(data.meta.status == 201){
// 将数据更新到页面
this.tableData.push(data.data);
this.$message({message: "添加用户成功",type: "success"});
// 关闭窗口
this.dialogFormVisible = false
}
})
},
2.8 修改用户信息
绑定表单事件,传入 scope.row 以显示现有用户数据,做表单读入展示
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini" @click="editUserShow(scope.row)" plain></el-button>
<el-button type="primary" icon="el-icon-check" size="mini" plain></el-button>
<el-button type="primary" icon="el-icon-delete" size="mini" @click="deleteUser(scope.row.id)" plain></el-button>
</template>
添加修改用户信息的弹窗,并在弹窗表单中展示用户信息
<!-- 修改用户弹窗 -->
<el-dialog title="添加用户" :visible.sync="editUser">
<el-form :model="edit">
<el-form-item label="姓名" label-width="90px">
<el-input disabled v-model="edit.username" ></el-input>
</el-form-item>
<el-form-item label="邮箱" label-width="90px">
<el-input v-model="edit.email" ></el-input>
</el-form-item>
<el-form-item label="电话" label-width="90px">
<el-input v-model="edit.mobile" ></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<!-- 点击取消或确定修改dialogFormVisible=false关闭窗口 -->
<el-button @click="editUser = false">取 消</el-button>
<el-button type="primary" @click="editUserPut">确 定</el-button>
</div>
</el-dialog>
// 弹窗并显示用户数据 用于修改表单
editUserShow(users){
this.editUser = true; // 弹窗
this.edit = users; // 直接使用表单数据
},
// 修改用户信息 入库
editUserPut(){
var id = this.edit.id;
var email = this.edit.email;
var mobile = this.edit.mobile;
this.$myHttp({
url: `users/${id}`,
method: "put",
data:{email,mobile},
headers: { Authorization: window.localStorage.getItem("token") }
}).then(res=>{
// console.log(res);
if(res.data.meta.status == 200){
this.editUser = false; // 关闭窗口
this.getUserData(); // 重新获取数据
this.$message({message: "修改用户成功",type: "success"});
}
})
}
2.9 修改用户角色
Select 选择器->基础用法
下拉框
<!-- 分配角色弹窗 -->
<el-dialog title="分配角色" :visible.sync="showRole">
<el-form :model="role">
<el-form-item label="当前用户" label-width="90px">
<el-input disabled v-model="role.username" ></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="roleId" placeholder="请选择活动区域">
<el-option
v-for="item in roleList"
:key="item.key"
:label="item.roleName"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
{
{roleId}}
<!-- 点击取消或确定修改dialogFormVisible=false关闭窗口 -->
<el-button @click="showRole = false">取 消</el-button>
<el-button type="primary" @click="roleUserPut">确 定</el-button>
</div>
</el-dialog>
弹窗后,获取全部角色遍历到 el-option
,获取用户id及修改后的角色,请求接口即可;
第3章 权限管理
3.1 权限列表
添加路由及组件文件
import Rights from '@/components/rights/rights'
{path:'rights',name:'rights',component:Rights}
<template>
<div>
<el-table
height="850"
ref="singleTable"
:data="tableData"
highlight-current-row
style="width: 100%">
<el-table-column
type="index"
width="50">
</el-table-column>
<el-table-column
property="authName"
label="权限名称"
width="120">
</el-table-column>
<el-table-column
property="path"
label="路径"
width="120">
</el-table-column>
<el-table-column property="一级" label="层级">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data(){
return {
tableData:[]
}
},
mounted() {
this.getlist();
},
methods:{
getlist(){
this.$myHttp({
url:'rights/list',
method:'get',
headers: { Authorization: window.localStorage.getItem("token") }
}).then(backs=>{
// console.log(backs);
this.tableData = backs.data.data;
})
}
}
}
</script>
<style>
.el-main {
line-height: 30px;
}
</style>
只要在el-table
元素中定义了height=500
属性,即可实现固定表头的表格,而不需要额外的代码。
修改层级展示
<el-table-column property="level" label="层级">
<template slot-scope="scope">
<span v-if="scope.row.level==='0'">一级</span>
<span v-else-if="scope.row.level==='1'">二级</span>
<span v-if="scope.row.level==='2'">三级</span>
</template>
</el-table-column>
3.2 角色列表
添加路由及组件
import Roles from '@/components/roles/roles'
{path:'roles',name:'roles',component:Roles},
<template>
<el-table :data="tableData5" style="width: 100%">
<!-- 折叠内容 -->
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="商品名称">
<span>{
{ props.row.name }}</span>
</el-form-item>
<el-form-item label="所属店铺">
<span>{
{ props.row.shop }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<!-- 表头及折叠按钮 -->
<el-table-column
label="角色名称"
prop="id">
</el-table-column>
<el-table-column
label="角色描述"
prop="name">
</el-table-column>
<el-table-column
label="操作"
prop="desc">
</el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData5: [{
id: '12987122',
name: '好滋好味鸡蛋仔',
category: '江浙小吃、小吃零食',
desc: '荷兰优质淡奶,奶香浓而不腻',
address: '上海市普陀区真北路',
shop: '王小虎夫妻店',
shopId: '10333'
}, {
id: '12987123',
name: '好滋好味鸡蛋仔',
category: '江浙小吃、小吃零食',
desc: '荷兰优质淡奶,奶香浓而不腻',
address: '上海市普陀区真北路',
shop: '王小虎夫妻店',
shopId: '10333'
}]
}
}
}
</script>
<style>
.demo-table-expand {
font-size: 0;
}
.demo-table-expand label {
width: 90px;
color: #99a9bf;
}
.demo-table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
width: 50%;
}
.el-main{
line-height:20px;
}
</style>
<!-- 表头及折叠按钮 -->
<el-table-column
label="角色名称"
prop="roleName">
</el-table-column>
<el-table-column
label="角色描述"
prop="roleDesc">
</el-table-column>
<el-table-column
label="操作"
prop="desc">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini" circle></el-button>
<el-button type="success" icon="el-icon-check" size="mini" circle></el-button>
</template>
</el-table-column>
data() {
return {
roleList: []
};
},
mounted() {
this.getrolelist();
},
methods: {
getrolelist() {
this.$myHttp({
url: "roles",
method: "get"
}).then(back => {
this.roleList = back.data.data;
});
}
}
Tag 标签->可移除标签
<!-- 折叠内容 -->
<el-table-column type="expand">
<template slot-scope="props">
<el-tag closable>可移除</el-tag>
</template>
</el-table-column>
分析角色数据,children
为上级角色中的子级角色;
<!-- 折叠内容 -->
<el-table-column type="expand">
<template slot-scope="scope">
{
{scope.row.children}}
<!-- <el-tag closable>{
{scope.row.children}} </el-tag> -->
</template>
</el-table-column>
<!-- 折叠内容 -->
<el-table-column type="expand">
<template slot-scope="scope">
<!-- Layout 布局 -->
<el-row>
<!-- 一级区域 -->
<el-col :span="6">
<!-- 一级内容展示 -->
<el-tag closable>{
{scope.row.children[1].authName}} </el-tag> >
</el-col>
<el-col :span="18">
<!-- 二级区域 -->
<el-row>
<el-col :span="6">
<!-- 二级内容 -->
<el-tag closable type="success">{
{scope.row.children[0].children[0].authName}} </el-tag> >
</el-col>
<el-col :span="18">
<!-- 三级内容 -->
<el-tag closable type="warning">{
{scope.row.children[1].children[0].children[0].authName}}</el-tag>
<el-tag closable type="warning">{
{scope.row.children[1].children[0].children[1].authName}}</el-tag>
<el-tag closable type="warning">{
{scope.row.children[1].children[0].children[2].authName}}</el-tag>
</el-col>
</el-row>
</el-col>
</el-row>
</template>
</el-table-column>
循环遍历所有层级角色
<!-- 折叠内容 -->
<el-table-column type="expand">
<template slot-scope="scope">
<!-- Layout 布局 -->
<el-row class="rowmargin" v-for="item1 in scope.row.children" :key="item1.id">
<!-- 一级区域 -->
<el-col :span="6">
<!-- 一级内容展示 -->
<el-tag closable>{
{item1.authName}} </el-tag> >
</el-col>
<el-col :span="18">
<!-- 二级区域 -->
<el-row v-for="item2 in item1.children" :key="item2.id">
<el-col :span="6">
<!-- 二级内容 -->
<el-tag closable type="success">{
{item2.authName}} </el-tag> >
</el-col>
<el-col :span="18">
<!-- 三级内容 -->
<el-tag v-for="item3 in item2.children" :key="item3.id" closable type="warning">{
{item3.authName}} </el-tag>
</el-col>
</el-row>
</el-col>
</el-row>
<!-- 判断没有权限 -->
<el-row v-if="scope.row.children.length==0">
<template><el-tag type="danger">木有权限</el-tag></template>
</el-row>
</template>
</el-table-column>
……
.el-tag{
margin-top: 10px;
margin-right:5px;
}
<style>
3.3 删除角色权限
绑定close事件
页面元素删除
<!-- 三级内容 -->
<el-tag @close="closeTag(item2,key3)" v-for="(item3,key3) in item2.children" :key="item3.id" closable type="warning">{
{item3.authName}} </el-tag>
// 删除角色权限
closeTag(item,key){
// 数组引用传递,直接删除即可
// console.log(item,key)
item.children.splice(key,1);
}
服务器删除
<el-col :span="18">
<!-- 三级内容 -->
<el-tag @close="closeTag(item2,key3,scope.row.id,item3.id)" v-for="(item3,key3) in item2.children" :key="item3.id" closable type="warning">{
{item3.authName}} </el-tag>
</el-col>
// 删除角色权限
closeTag(item,key,roleId,rightId){
// item 要删除元素所在父级数组
// key 要删除元素所在父级数组下标
item.children.splice(key,1);
// roleid 角色ID,rightId权限ID
// console.log(roleId,rightId);
this.$myHttp({
url:`roles/${roleId}/rights/${rightId}`,
method:'delete'
}).then(back=>{
let {meta} = back.data;
// console.log(meta);
if(meta.status == 200){
this.$message({message:meta.msg,type:'success'});
}
})
}
3.4 修改角色权限
展示面板:
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini" circle></el-button>
<el-button type="success" icon="el-icon-check" size="mini" @click="rightsShow" circle></el-button>
</template>
<!-- 修改角色授权面板 -->
<el-dialog title="修改角色权限" :visible.sync="isrightsShow">
<div slot="footer" class="dialog-footer">
<el-tree show-checkbox="true" :data="rightsList" :props="defaultProps" ></el-tree>
<!-- 点击取消或确定修改dialogFormVisible=false关闭窗口 -->
<el-button @click="isrightsShow = false">取 消</el-button>
<el-button type="primary" @click="rightsPut">确 定</el-button>
</div>
</el-dialog>
return {
// 所有权限列表
rightsList:[],
// 设置展示内容
defaultProps: {
children: 'children',
label: 'authName'
},
// 展示修改角色权限面板
rightsShow() {
// 获取所有角色权限
this.$myHttp({
url:'rights/tree',
method:'get'
}).then(back=>{
let {data,meta} = back.data;
this.rightsList= data;
})
this.isrightsShow = true;
},
选中角色拥有的权限:
在点击按钮式,将所有角色的所有信息传入展示面板事件中:
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini" circle></el-button>
<el-button @click="rightsShow(scope.row)" type="success" icon="el-icon-check" size="mini" circle></el-button>
</template>
<!-- 修改角色授权面板 -->
<el-dialog title="修改角色权限" :visible.sync="isrightsShow">
<div slot="footer" class="dialog-footer">
<!--
default-expand-all 默认展开所有节点
node-key="id" 将id设置为节点的唯一主键
:default-checked-keys=[] 被选中主键的数组
:props="defaultProps" 设置显示的内容
show-checkbox 节点可被选中
-->
<el-tree
default-expand-all
node-key="id"
:default-checked-keys="defaultChecked"
show-checkbox
:data="rightsList"
:props="defaultProps" ></el-tree>
<!-- 点击取消或确定修改dialogFormVisible=false关闭窗口 -->
<el-button @click="isrightsShow = false">取 消</el-button>
<el-button type="primary" @click="rightsPut">确 定</el-button>
</div>
</el-dialog>
data() {
return {
// 所有权限列表
rightsList: [],
// 设置展示内容
defaultProps: {
children: "children",
label: "authName"
},
// 默认选中的节点数组
defaultChecked: [],
// 控制角色权限面板
isrightsShow: false,
// 所有角色数据列表
roleList: []
};
},
……
// 展示修改角色权限面板
rightsShow(row) {
// 获取所有角色权限
this.$myHttp({
url: "rights/tree",
method: "get"
}).then(back => {
let { data, meta } = back.data;
// 显示所有权限
this.rightsList = data;
});
// 遍历row,获取当前角色选中的所有权限,写入数组
this.defaultChecked = [];
// 在遍历赋值前,先清空数据,以免受其他数据影响
var rr = row.children;
rr.forEach(item1 => {
item1.children.forEach(item2=>{
item2.children.forEach(item3=>{
// 只获取第三季选中即可
this.defaultChecked.push(item3.id);
})
});
});
console.log(this.defaultChecked);
// 控制显示窗口
this.isrightsShow = true;
},
提交数据入库:
// 提交修改角色权限
rightsPut() {
// 在树形控件 中添加 ref="tree" 的属性,在此使用
// elUI 中提供两个方法getCheckedKeys、getHalfCheckedKeys
// 获取已选中的节点key
var arr1 = this.$refs.tree.getCheckedKeys();
var arr2 = this.$refs.tree.getHalfCheckedKeys();
// concat() 合并两个数组的元素
// join() 将数组的值以逗号隔开转为字符串
var checkedKeys = arr1.concat(arr2).join();
this.$myHttp({
// 点击打开窗口是,保存角色id,在此获取使用
url:`roles/${this.roleId}/rights`,
method:'post',
data:{rids:checkedKeys}
}).then(back=>{
let {data,meta} = back.data;
if(meta.status == 200){
this.isrightsShow = false; // 关闭窗口
this.getrolelist(); // 刷新数据
this.$message({message:meta.msg,type:'success'}); // 提示成功
}
})
},
3.5 权限限制
对角色分配了权限后,我们并没有做限制,其实接口文档中左侧菜单权限
已经提供了相应的接口:
src/components/home/home.vue
<el-menu
unique-opened
:router="true"
class="el-menu-vertical-demo"
>
<el-submenu
v-for="item in menusList"
:key="item.id"
:index="item.id.toString()" >
<template slot="title">
<i class="el-icon-location"></i>
<span>{
{item.authName}} {
{item.id}}</span>
</template>
<el-menu-item
v-for="item2 in item.children"
:key="item2.id"
:index="item2.path">
<i class="el-icon-menu"></i>
{
{item2.authName}} {
{item2.path}}
</el-menu-item>
</el-submenu>
</el-menu>
<script>
export default {
// 使用生命周期的钩子函数,判断token
mounted() {
// 获取token
var token = window.localStorage.getItem("token");
if (!token) {
// 错误提示
this.$message.error("请登录");
// 跳转到登录页面
this.$router.push({ name: "Login" });
}else{
// 登录后,获取左侧菜单权限
this.$myHttp({
url:'menus',
method:'get',
}).then(back=>{
let {data,meta} = back.data;
if(meta.status == 200){
console.log(data);
this.menusList = data
}
})
}
},
data() {
return {
menusList:[],
msg: "we"
};
},
methods:{
loginOut(){
window.localStorage.removeItem('token')
this.$message({
message: "您已经退出,继续操作请重新登录",
type: "success"
});
this.$router.push({ name: "Login" });
}
}
};
</script>
3.6 导航守卫
导航守卫: https://router.vuejs.org/zh/guide/advanced/navigation-guards.html
var router = new Router({……})
// 配置路由的导航守卫
router.beforeEach((to, from, next) => {
// 如果访问登录的路由地址,放过
if (to.name === 'Login') {
next();
} else {
// 如果请求的不是登录页面,验证token
// 1. 获取本地存储中的token
const token = localStorage.getItem('token');
if (!token) {
// 2. 如果没有token,跳转到登录
next({
name: 'Login'
});
} else {
// 3. 如果有token,继续往下执行
next();
}
}
});
export default router;
项目打包及加载优化
打包命令:npm run build
打包完成后,直接将dist文件夹内容复制到服务器根目录即可;
我们的项目是很多组件组成的页面,但是,每次发送请求不管请求的是哪个路由的那个组件,很明显的都会将所有内容一次性全部加载出来,影响网站加载速度;如果我们可以在用户请求不同路由时,根据请求加载不同的页面,就会很大程度上提高页面的加载速度;
路由懒加载: https://router.vuejs.org/zh/guide/advanced/lazy-loading.html
路由懒加载的工作就是在打包时,将路由文件分离出来,在请求时,需要哪个路由,再去请求相关文件;
用法:将路由引入的组件分别打包到不同的 js 文件;
打包完成后,很明显的在 JS 文件夹中多了一个js文件;
然后我们可以将所有的组件全部改为路由懒加载模式:
const Login = () => import('@/components/login/login');
const Home = () => import('@/components/home/home');
const UserList = () => import('@/components/userlist/user-list');
const RoleList = () => import('@/components/rolelist/role-list');
const RightsList = () => import('@/components/rightslist/rights-list');
const GoodsList = () => import('@/components/goodslist/goods-list');
const GoodsCategories = () => import('@/components/goodscategories/goods-categories');
const GoodsAdd = () => import('@/components/goodsadd/goods-add');
const Report = () => import('@/components/report/report');
const Order = () => import('@/components/orders/orders');
const Params = () => import('@/components/params/params');
但这是不够的,我们知道,很多组件都是可以用 CDN 加载的;
1:找到 cdn 地址,直接在index.html 中加入地址,注意,cdn 引入版本要和项目中的版本保持一致;
<body>
<div id="app">
</div>
<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
<!-- built files will be auto injected -->
</body>
2:修改 webpack 配置文件 https://www.webpackjs.com/configuration/externals/