Login.vue中的登录按钮事件
const res = await http.post('/login', data)
if (res.data.code === 200) {
//存菜单
let menuList = res.data.data.routers
localStorage.setItem('menuList', JSON.stringify(menuList))
store.commit("setMenuList", menuList);
//存路由
let routes = res.data.data.components
localStorage.setItem('routes', JSON.stringify(routes))
store.commit("setRouters", routes);
router.push({
path: "/dashboard"
});
}
在router/index.js中定义基本的路由信息,动态生成的路由默认放在Home组件
1、未使用动态路由的写法 ,一般会把所有路由信息写到home的children数组中
import {createRouter, createWebHashHistory} from "vue-router";
import store from '../store/index'
const routes = [
{
path: "/login",
name: "login",
component: () => import ( /* webpackChunkName: "login" */ "../views/login/Login.vue"),
meta: {
title: '登录',
},
},
{
path: '/register',
name: 'register',
component: () => import(/* webpackChunkName: "register" */ '../views/login/Register.vue'),
meta: {
title: '注册',
},
},
{
path: "/home",
name: "home",
component: () => import ( "../components/Home.vue"),
children: [
{
path: '/index',
component: () => import('../views/Index.vue'),
meta: {
title: 'Index',
requiresAuth: true
}
},
{
path: '/test',
component: () => import('../views/Test.vue'),
meta: {
title: 'Test',
requiresAuth: true
}
},
]
}
];
const router = createRouter({
history: createWebHashHistory(),
routes
});
2、当使用动态路由时, 默认向Home.vue中添加children子路由
import {createRouter, createWebHashHistory} from "vue-router";
import store from '../store/index'
import dealWithRoute from "./dealWithRoute";
const routes = [
{
path: "/login",
name: "login",
component: () => import ( /* webpackChunkName: "login" */ "../views/login/Login.vue"),
meta: {
title: '登录',
},
},
{
path: '/register',
name: 'register',
component: () => import(/* webpackChunkName: "register" */ '../views/login/Register.vue'),
meta: {
title: '注册',
},
},
{
path: "/home",
name: "home",
component: () => import ( "../components/Home.vue"),
}
];
const router = createRouter({
history: createWebHashHistory(),
routes
});
在router.beforeEach中获取登录时所存储的数据
当生成动态路由后一旦刷新页面,页面会变成空白,需要重新从localStorage取值渲染
router.addRoute第一个参数是动态路由所在“位置”,是指定“位置”的name属性
router.beforeEach((to, from, next) => {
// console.log('to, from', to, from);
let isLoadRouters = store.state.asyncRoutesMark
let token = sessionStorage.getItem('token')
let routes = JSON.parse(localStorage.getItem('routes'))
// 有token routes
if (to.path == '/login') {
next()
} else {
//用户已登录
if (token && JSON.stringify(routes) != '[]') {
if (isLoadRouters) {
// console.log('路由已添加,直接跳转到目标页面');
next()
} else {
//解决刷新页面空白
//console.log('重新加载路由,并跳转到目标页');
let route = JSON.parse(localStorage.getItem('routes'))
store.commit('setRouters', route);
store.commit('setAsyncRoutesMark', true);
//添加动态路由
let menuList = JSON.parse(localStorage.getItem('menuList'))
dealWithRoute(menuList)
next({...to,replace: true})
}
} else {
// console.log('无登录信息,跳转到登录页');
store.commit('setMenuList', []);
store.commit('setAsyncRoutesMark', false);
sessionStorage.setItem('token', '');
localStorage.setItem('menuList', JSON.stringify([]));
localStorage.setItem('routes', JSON.stringify([]));
next(`/login`)
}
}
});
export default router;
//处理树形数据
//dealWithRoute.js
import router from './index';
import {RouterView} from "vue-router";
const dealWithRoute = (data, parent = 'home') => {
for (let item of data) {
//多级菜单
if (item.children && item.children.length > 0) {
router.addRoute(parent, {
path: item.path,
name: item.path.split('/')[1],
component: RouterView,
meta: {
title: item.name,
requiresAuth: true
}
})
dealWithRoute(item.children, item.path.split('/')[1])
} else { //一级菜单
router.addRoute(parent, {
path: item.path,
name: item.name,
component: () => import(`../views/${item.component}`),
meta: {
title: item.name,
requiresAuth: true
}
});
}
}
};
export default dealWithRoute;
store/index.js
import {createStore} from 'vuex'
export default createStore({
state: {
asyncRoutesMark: false,
menu: [],
routers: []
},
mutations: {
setAsyncRoutesMark(state, data) {
state.asyncRoutesMark = data;
},
setMenuList(state, data) {
state.menu = data
},
setRouters(state, data) {
state.routers = data;
}
},
})