每个系统都有自己的登录登出逻辑,而我们前端所要做的其实是请求后台,拿到登录权限,带上登录权限,获取用户信息和菜单信息。 在vue项目开发当中,一般都是在全局路由钩做这一系列判断。
① 在登录页面输入用户名和密码
② 调用后台接口进行验证
③ 通过验证之后,根据后台的响应状态跳转到项目主页
// 路由权限信息
router.beforeEach((to, from, next) => {
NProgress.start();
// 如果需要权限
if (to.meta.requireAuth) {
// 是否有token
if (localStorage.getItem("token")) {
// 有个token放行
next();
} else {
// 如果没有跳转到首页,查询参数redirect是当前页的path
Message({
message: '需要先登录!',
type: 'warning'
});
next("/?redirect=" + to.path)
}
} else {
// 如果没有权限那么就直接放行
next();
}
})
基于token的方式实现退出比较简单,只需要销毁本地的token即可。 这样,后续的请求就不会携带token,必须重新登录生成一个新的token之后才可以访问页面
<el-button type="info" @click="logout">退出el-button>
methods: {
logout() {
localStorage.removeItem('token')
this.$router.push('/login')
}
}
以前的菜单路由是直接写死在前端,但是当我们直接访问这个路由时,用户还是可以进入到这个功能页面;后来直接改成动态添加路由的方式router.addRoutes。
// 导入获取菜单的api
import {GetUserMenu} from '@/api/permission'
// 导入路由
import router from '@/router/index.js'
export default {
state:{
// 全局菜单数组
menus:[],
},
mutations:{
// 更新菜单
setMenu(state,data){
state.menus = data;
}
},
actions:{
getMenu(context,data){
return new Promise(resolve=>{
// 获取当前的菜单
GetUserMenu(data)
.then(res=>{
if(res.data.code==0){
console.log(res.data)
// 更新store中的menus
context.commit("setMenu",res.data.list);
// 把菜单映射为路由配置
// 定义子路由数组
let children =[];
// 把菜单进行遍历
res.data.list.forEach(item=>{
// 如果当前对象没有children子元素
if(!item.children){
// 直接转换为路由配置添加到children数组里面
children.push({
name:item.name,
path:item.linkname,
component:()=>import('@/views'+item.component)
})
}else{
// 如果有子元素
for(let i=0;i<item.children.length;i++){
// 遍历子元素并报所有的子元素转为路由配置 添加到children数组里面
children.push({
name:item.children[i].name,
path:item.children[i].linkname,
component:()=>import('@/views'+item.children[i].component)
})
}
}
})
// children.push({"path":'',redirect:'/admin/dash'})
// 动态的配置路由 admin路由(没有权限的用户进入不到他不对应的菜单)
var admin ={
name: 'admin',
path: '/admin',
component: ()=>import('@/views/admin/AdminView.vue'),
children
}
router.addRoute(admin)
resolve(admin);
}
})
})
}
}
}
import { createRouter, createWebHashHistory } from 'vue-router'
import store from '@/store/index.js'
const routes = [
{
path: '/',
name: 'login',
// component: HomeView
component:()=>import('../views/user/LoginView.vue')
},
{
path:"/admin",
name:"admin",
component:()=>import('../views/admin/AdminView.vue'),
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
// var count = 0;
router.beforeEach(async (to,from,next)=>{
if(to.fullPath.includes("/admin")&&store.state.permission.menus.length==0){
await store.dispatch("getMenu")
// count++;
next({path:to.fullPath});
}else{
next();
}
})
export default router
<template>
<div>
员工管理
</div>
</template>
<script>
import { GetStaffList, } from '@/api/employees.js'
export default {
data() {
return {
staffList: '',
searchObj: {
id: ""
},
}
},
created() {
this.getStaffList()
},
methods: {
getStaffList() {
GetStaffList(this.searchObj)
.then(res => {
if (res.data.code == 0) {
console.log(res.data.data);
this.staffList = res.data.data;
} else {
alert(res.data.msg || "员工列表获取失败")
}
})
},
}
}
</script>
<template>
<div>员工管理
<el-form :inline="true" ref="searchRef" :model="searchObj">
<el-form-item label="id" prop="id">
<el-input v-model="searchObj.id" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getStaffList">查询</el-button>
<el-button type="primary" @click="resetSearch()">重置</el-button>
<el-button type="success" plain @click="showPost()">新增员工</el-button>
</el-form-item>
</el-form>
<el-table :data="staffList" stripe style="width: 100%">
<el-table-column prop="id" label="员工编号" width="180">
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
</el-table-column>
<el-table-column prop="shop" label="所属门店">
</el-table-column>
<el-table-column prop="tel" label="手机号">
</el-table-column>
<el-table-column prop="address" label="角色">
</el-table-column>
<el-table-column prop="state" label="状态">
</el-table-column>
<el-table-column prop="lastTime" label="最近登录时间">
</el-table-column>
<el-table-column prop="lastTime" label="编辑员工">
<template slot-scope="scope">
<el-button type="success" plain @click="showPut(scope)">编辑员工</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { GetStaffList } from '@/api/employees.js'
export default {
data() {
return {
staffList: '',
searchObj: {
id: ""
},
}
},
created() {
this.getStaffList()
},
methods: {
getStaffList() {
GetStaffList(this.searchObj)
.then(res => {
if (res.data.code == 0) {
console.log(res.data.data);
this.staffList = res.data.data;
} else {
alert(res.data.msg || "员工列表获取失败")
}
})
},
}
</script>
<van-popup v-model="show1">
<p>新增p>
<p>
请输入员工的编号
<el-input v-model="searchObjTo.id" placeholder="请输入员工的编号">el-input>
p>
<p>
请输入员工的姓名
<el-input v-model="searchObjTo.name" placeholder="请输入员工的姓名">el-input>
p>
<p>
请输入员工所属的门店
<el-input v-model="searchObjTo.shop" placeholder="请输入员工所属的门店">el-input>
p>
<p>
请输入员工的手机号
<el-input v-model="searchObjTo.tel" placeholder="请输入员工的手机号">el-input>
p>
<p>
请输入员工的角色
<el-input v-model="searchObjTo.address" placeholder="请输入员工的角色">el-input>
p>
<p>
请输入员工的状态
<el-input v-model="searchObjTo.state" placeholder="请输入员工的状态">el-input>
p>
<el-button type="success" @click="success1()">确认添加el-button>
<el-button type="danger" @click="danger1()">取消添加el-button>
van-popup>
data() {
return {
// 控制对话框显示与隐藏
show1: false
}
}
② 接下来我们要为“添加用户”按钮添加点击事件,在事件中将
show1设置为true,即显示对话框
<template>
<div>员工管理
<el-form :inline="true" ref="searchRef" :model="searchObj">
<el-form-item label="id" prop="id">
<el-input v-model="searchObj.id" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getStaffList">查询</el-button>
<el-button type="primary" @click="resetSearch()">重置</el-button>
<el-button type="success" plain @click="showPost()">新增员工</el-button>
</el-form-item>
</el-form>
<el-table :data="staffList" stripe style="width: 100%">
<el-table-column prop="id" label="员工编号" width="180">
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
</el-table-column>
<el-table-column prop="shop" label="所属门店">
</el-table-column>
<el-table-column prop="tel" label="手机号">
</el-table-column>
<el-table-column prop="address" label="角色">
</el-table-column>
<el-table-column prop="state" label="状态">
</el-table-column>
<el-table-column prop="lastTime" label="最近登录时间">
</el-table-column>
<el-table-column prop="lastTime" label="编辑员工">
<template slot-scope="scope">
<el-button type="success" plain @click="showPut(scope)">编辑员工</el-button>
</template>
</el-table-column>
</el-table>
<van-popup v-model="show1">
<p>新增</p>
<p>
请输入员工的编号
<el-input v-model="searchObjTo.id" placeholder="请输入员工的编号"></el-input>
</p>
<p>
请输入员工的姓名
<el-input v-model="searchObjTo.name" placeholder="请输入员工的姓名"></el-input>
</p>
<p>
请输入员工所属的门店
<el-input v-model="searchObjTo.shop" placeholder="请输入员工所属的门店"></el-input>
</p>
<p>
请输入员工的手机号
<el-input v-model="searchObjTo.tel" placeholder="请输入员工的手机号"></el-input>
</p>
<p>
请输入员工的角色
<el-input v-model="searchObjTo.address" placeholder="请输入员工的角色"></el-input>
</p>
<p>
请输入员工的状态
<el-input v-model="searchObjTo.state" placeholder="请输入员工的状态"></el-input>
</p>
<el-button type="success" @click="success1()">确认添加</el-button>
<el-button type="danger" @click="danger1()">取消添加</el-button>
</van-popup>
<van-popup v-model="show2" :data="editRow">
<p>
请输入员工的编号
<el-input v-model="editRow.id" placeholder="请输入员工的编号"></el-input>
</p>
<p>
请输入员工的姓名
<el-input v-model="editRow.name" placeholder="请输入员工的姓名"></el-input>
</p>
<p>
请输入员工所属的门店
<el-input v-model="editRow.shop" placeholder="请输入员工所属的门店"></el-input>
</p>
<p>
请输入员工的手机号
<el-input v-model="editRow.tel" placeholder="请输入员工的手机号"></el-input>
</p>
<p>
请输入员工的角色
<el-input v-model="editRow.address" placeholder="请输入员工的角色"></el-input>
</p>
<p>
请输入员工的状态
<el-input v-model="editRow.state" placeholder="请输入员工的状态"></el-input>
</p>
<el-button type="success" @click="success2()">确认修改</el-button>
<el-button type="danger" @click="danger2()">取消修改</el-button>
</van-popup>
</div>
</template>
<script>
import { GetStaffList, GetStaffPost, GetStaffPut } from '@/api/employees.js'
export default {
data() {
return {
staffList: '',
searchObj: {
id: ""
},
show1: false,
show2: false,
searchObjTo: {
id: '',
name: '',
user_group: 1,
},
editRow: {},
editIndex: null
}
},
created() {
this.getStaffList()
},
methods: {
success1() {
//确认新增
this.getStaffPost()
this.show1 = false
},
danger1() {
//取消新增
this.show1 = false
},
success2() {
//确认修改
this.getStaffPut()
this.show2 = false;
},
danger2() {
//取消修改
this.show2 = false
},
showPut(scope) {
this.editRow = { ...scope.row };
this.editIndex = scope.$index
console.log(this.editRow);
this.show2 = true;
console.log('修改前', this.staffList[this.editIndex]);
},
showPost() {
this.show1 = true;
},
resetSearch() {
this.searchObj.id = ''
this.getStaffList();
},
getStaffList() {
GetStaffList(this.searchObj)
.then(res => {
if (res.data.code == 0) {
console.log(res.data.data);
this.staffList = res.data.data;
} else {
alert(res.data.msg || "员工列表获取失败")
}
})
},
getStaffPost() {
// delete this.searchObjTo.user_group
console.log(this.searchObjTo);
GetStaffPost(this.searchObjTo)
.then(res => {
console.log('新增员工', res);
alert('新增成功',)
this.getStaffList()
}).catch(err => {
console.log(err);
alert('新增失败',)
})
},
getStaffPut() {
delete this.editRow.score
delete this.editRow.user_group
console.log('修改前', this.staffList[this.editIndex]);
GetStaffPut(this.editRow)
.then(res => {
if (res.data.code == 0) {
this.$message({
message: '修改成功',
type: 'success'
})
//隐藏编辑框
this.getStaffList()
// this.staffList[this.editIndex] = this.editRow
// console.log('修改前', this.staffList[this.editIndex]);
// console.log('修改后', this.editRow);
} else {
this.$message({
message: '修改失败',
type: 'warning'
})
}
console.log('编辑员工', res);
}).catch(err => {
console.log(err);
this.$message({
message: '修改失败',
type: 'warning'
})
})
}
}
}
</script>