1. Faça login para obter informações de roteamento
Evento do botão de login em 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"
});
}
2. Renderizar roteamento dinâmico
Defina informações básicas de roteamento em router /index.js e as rotas geradas dinamicamente são colocadas no componente Home por padrão.
1. Se o roteamento dinâmico não for usado, todas as informações de roteamento geralmente serão gravadas no array filhos de home.
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. Ao usar o roteamento dinâmico, a subrota secundária é adicionada a Home.vue por padrão.
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
});
Obtenha os dados armazenados no login em router.beforeEach
Depois que a página for atualizada após gerar uma rota dinâmica, a página ficará em branco e precisará ser renderizada novamente no localStorage.
O primeiro parâmetro de router.addRoute é o "local" da rota dinâmica, que é o atributo de nome que especifica o "local".
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;
3. código vuex
loja/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;
}
},
})