# 登录
# 技术点
vuex 的使用
登录信息存入 vuex
addRoutes 的使用
# 介绍
输入账号密码登陆成功后,接口会返回 token
,携带该 token
调用获取管理员信息接口,该接口会返回管理员信息和分配的菜单权限,分别存入 vuex
中。用户菜单会通过 router.addRoutes
动态添加到路由表中。
# 目录结构
└─ src
└─ pages
└─ login # 账号相关
└─ index.vue # 账号登录
# 登陆
methods: {
// 登陆方法
login() {
this.$refs.form.validate(async (valid) => {
if (valid) {
this.loading = true;
// 调用登录方法
const loginRes = await this.$store.dispatch("user/login", this.form);
if (loginRes.code !== 200) {
this.loading = false;
return;
}
// 获取管理员信息与菜单权限
const adminRes = await this.$store.dispatch("user/getInfo");
this.loading = false;
if (adminRes.code === 200) {
// 处理路由
let routes = adminRes.data.roles;
let asyncRoutes = this.filterAsyncRouter(routes); //过滤路由
let isAdd = false; // 防止动态路由重复添加
if (!isAdd) {
router.addRoutes(asyncRoutes); //动态添加路由
}
isAdd = true;
this.$router.replace(
this.$route.query.redirect
? this.$route.query.redirect
: asyncRoutes[0].path
);
}
} else {
return false;
}
});
},
// 遍历后台传来的路由字符串,转换为组件对象
filterAsyncRouter(asyncRoutes) {
let accessedRouters = asyncRoutes.filter((route) => {
if (route.component) {
//Layout组件特殊处理
if (route.component === "Layout") {
route.component = Layout;
} else {
try {
// 引入组件
route.component = _import(route.component);
} catch (e) {
console.info(
"%c 当前路由 " +
route.component +
".vue 不存在,因此无法导入组件,请检查接口数据和组件是否匹配,并重新登录,清空缓存!",
"color:red"
);
}
}
}
// 存在子路由时递归遍历子路由
if (route.children && route.children.length) {
route.children = this.filterAsyncRouter(route.children);
}
return true;
});
return accessedRouters;
},
},
# 处理用户刷新
登录后用户路由菜单会写入 vuex
与 storage
中,但用户如果刷新页面,addRouter
中的路由会丢失,所以在路由 router
文件中,需要再次执行 addRouter
操作,并在 main.js
中引入。
const _import = require('./_import_' + process.env.NODE_ENV) // 引入组件方式
import router from "@/router/index"
import Layout from '@/pages/Layout'
import store from '@/store/index'
// 如果存在路由菜单,则执行以下代码
if (store.state.user.menus && Array.isArray(store.state.user.menus)) {
const routes = store.state.user.menus
let asyncRoutes = filterAsyncRouter(routes) //过滤路由
let isAdd = false; //
if (!isAdd) {
router.addRoutes(asyncRoutes) //动态添加路由
};
isAdd = true
}
function filterAsyncRouter(asyncRoutes) { //遍历后台传来的路由字符串,转换为组件对象
const accessedRouters = asyncRoutes.filter(route => {
if (route.component) {
if (route.component === 'Layout') { //Layout组件特殊处理
route.component = Layout
} else {
route.component = _import(route.component)
}
}
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children)
}
return true
})
return accessedRouters
}
在 main.js
中引入,以便用户每次刷新页面时,执行该路由方法。
import './router/promission'
← 5.2.3 详情页布局 5.4 影视列表 →