2. 登录权限 & 导航守卫
安装缓存插件
npm i js-cookie
在 store 文件中,创建 user.js 文件,用于缓存输入的内容。
import Cookie from "js-cookie";
export default {
state: {
token: "",
},
mutations: {
// 设置cookie
setToken(state, val) {
(state.token = val), Cookie.set("token", val); //cookie的名称,传入的值
},
// 清除cookie
clearToken(state) {
(state.token = ""), Cookie.remove("token");
},
// 获取cookie
getToken(state) {
// 如果当前的缓存中有token,直接获取。如果没有,要从state中获取
state.token = Cookie.get("token") || state.token;
},
},
};
在 ./store/index.js 中导入
import Vue from 'vue'
import Vuex from 'vuex'
import tab from './tab'
import user from './user'
// 全局使用Vuex
Vue.use(Vuex)
export default new Vuex.Store({
// 模块化定义
modules:{
tab,
user
}
})
main.js 中添加前置路由守卫
// 前置路由守卫
router.beforeEach((to, from, next) => {
store.commit('getToken') //防止页面刷新后vuex丢失token信息
const token = store.state.user.token
// 如果token不存在,并且当前页不是登录页
if(!token && to.name !== 'login') {
next({name: 'login'}) // 返回登录页
} else if(token && to.name === 'login'){
next({name: 'home'})
} else {
next()
}
})
2. 登录接口逻辑
./api/mockServerData/permission.js,用于定义接口相关的逻辑
// 接口的相关逻辑
import Mock from 'mockjs'
export default {
// 模拟菜单权限,接收传递进来的参数
getMenu: config => {
console.log(config);
const { username, password } = JSON.parse(config.body)
console.log(JSON.parse(config.body))
// 先判断用户是否存在
// 判断账号和密码是否对应
if (username === 'admin' && password === 'admin') {
return {
code: 20000,
data: {
menu: [
{
path: '/home',
name: 'home',
label: '首页',
icon: 's-home',
url: 'home/index'
},
{
path: '/mall',
name: 'mall',
label: '商品管理',
icon: 'video-play',
url: 'mall/index'
},
{
path: '/user',
name: 'user',
label: '用户管理',
icon: 'user',
url: 'User/index'
},
{
label: '其他',
icon: 'location',
children: [
{
path: '/page1',
name: 'page1',
label: '页面1',
icon: 'setting',
url: 'other/pageOne.vue'
},
{
path: '/page2',
name: 'page2',
label: '页面2',
icon: 'setting',
url: 'other/pageTwo.vue'
}
]
}
],
token: Mock.Random.guid(),
message: '获取成功'
}
}
} else if (username === 'xiaoxiao' && password === 'xiaoxiao') {
return {
code: 20000,
data: {
menu: [
{
path: '/',
name: 'home',
label: '首页',
icon: 's-home',
url: 'home/index'
},
{
path: '/mall',
name: 'mall',
label: '商品管理',
icon: 'video-play',
url: 'mall/index'
}
],
token: Mock.Random.guid(),
message: '获取成功'
}
}
} else {
return {
code: -999,
data: {
message: '密码错误'
}
}
}
}
}
在 mock.js 中进行接口拦截
import permissionApi from './mockServerData/permission'
Mock.mock(/permission\/getMenu/, 'post', permissionApi.getMenu)
3. 菜单权限功能
动态添加路由,在 tab.js 中定义 menu 空数组
menu: []
在 tab.js 的 mutations 中添加修改方法
setMenu(state, val) {
state.menu = val
Cookie.set('menu', JSON.stringify(val))
},
clearMenu(state) {
state.menu = []
Cookie.remove('menu')
},
addMenu(state, router) {
if(!Cookie.get('menu')) {
return
}
// 转成对象
const menu = JSON.parse(Cookie.get('menu'))
state.menu = menu
const menuArray = []
menu.forEach(item => {
// 有二级菜单的数据
if(item.children) {
item.children = item.children.map(item => {
item.component = () => import(`../views/${item.url}`)
return item
})
menuArray.push(...item.children)
// 一级菜单
}else{
item.component = () => import(`../views/${item.url}`)
menuArray.push(item)
}
})
// 路由的动态添加
menuArray.forEach(item => {
router.addRoute('Main', item)
})
}
login.vue 中添加方法
login() {
getMenu(this.form).then((res) => {
console.log(res, "res");
// 接口调用成功
if (res.code === 20000) {
// 登录成功后,清除当前路由
this.$store.commit("clearMenu");
// 设置路由,传入数据
this.$store.commit("setMenu", res.data.menu);
// 设置token,传入接口的数据
this.$store.commit("setToken", res.data.token);
// 动态添加路由,传入router 实例
this.$store.commit("addMenu", this.$router);
// 页面跳转
this.$router.push({ name: "home" });
} else {
//失败的提示
this.$message.warning(res.data.message);
}
});
}
这样就可以把 CommonAside.vue 中写死的数据去掉,只留 menu: []。
.router/index.js 中里面的数据都删掉,只保留 children: []。
在 CommonAside.vue 中定义 asyncMenu(),用来获取 menu
computed: {
noChildren() {
// 过滤出来没有子项目的数据
return this.asyncMenu.filter((item) => !item.children);
},
hasChildren() {
// 过滤出有子项目的数据
return this.asyncMenu.filter((item) => item.children);
},
isCollapse() {
return this.$store.state.tab.isCollapse;
},
asyncMenu() {
// 获取menu
return this.$store.state.tab.menu
}
}
登录成功
Ⅱ、权限管理问题 & 退出登录
1. 刷新白屏的解决方法
main.js 中,在 vue实例生成前, created 钩子中调用动态路由的方法。
created() {
store.commit('addMenu', router)
}
2. 权限管理
已经登录后,不应该还能访问登录页面,而是让它跳转到首页。
在 main.js 中修改路由守卫
router.beforeEach((to, from, next) => {
store.commit('getToken') //防止页面刷新后vuex丢失token信息
const token = store.state.user.token
// 如果token不存在,并且当前页不是登录页
if(!token && to.name !== 'login') {
next({name: 'login'}) // 返回登录页
} else if(token && to.name === 'login'){
next({name: 'home'})
} else {
next()
}
})
3. 退出功能
在 CommonHeader.vue 中添加退出功能
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人中心</el-dropdown-item>
<el-dropdown-item @click.native="logOut">退出</el-dropdown-item>
</el-dropdown-menu>
logOut() {
this.$store.commit("clearToken"); //清除token
this.$store.commit("clearMenu"); //清除menu
this.$router.push("/login"); //跳转到登录界面
}
点击退出,返回到登录界面
收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!