使用vite4、vue3、vue-router4搭建动态路由的时候遇到的问题及解决方法解决!!
我使用的是登录接口返回菜单,使用pinia存储菜单数据,使用pinia-plugin-persist加js-cookie进行持久化存储数据
以下是我运行正常的代码
- 存储登录信息的store(useLogin)
// useLogin.js
import { defineStore } from 'pinia'
import { cookiesStorage } from '../utils'
export const useLogin = defineStore("useLogin", {
state() {
return {
token: '',
menus: []
}
},
getters: {
getToken() {
return this.token
}
},
actions: {
setLoginInfo({ token = '', menus = [] }) {
this.token = token
this.menus = menus
}
},
persist: {
enabled: true,
strategies: [
{
storage: cookiesStorage,
paths: ['token', 'menus']
},
]
}
})
- utils.js
// utils.js
import Cookies from "js-cookie";
const modules = import.meta.glob("../views/**/**.vue");
export const cookiesStorage = {
setItem(key, state) {
return Cookies.set(key, state, { expires: 3 })
},
getItem(key) {
return Cookies.get(key)
}
}
/**
*
* @param {Array} children chilren路由
* @param {Object} item 当前路由
* @returns import
*/
function showRouterView(children, item) {
let hasChildren = children.length > 0
let allHidden = hasChildren && children.every(it => it.hidden)
if (allHidden || children.length === 0) {
return modules[`../views${item.path}.vue`]
}
return () => import(/* @vite-ignore */ `../components/parentRoute/parentRoute.vue`)
}
/**
* 路由扁平化转换为tree
* @param {*} routes // 路由
* @param {*} pid // 对应父级的id,0为没有父路由
*/
export function generatorRoute(routes, pid = 0) {
let children = routes.filter(it => it.pid === pid)
if (!children.length) {
return []
}
let routers = children.map(item => {
let children = generatorRoute(routes, item.id)
let node = {
name: item.name || "",
path: item.path,
meta: {
hidden: !!item.hidden,
title: item.title,
icon: item.icon || ""
},
component: showRouterView(children, item),
}
return {
...node,
children
}
})
return routers
}
- 登录返回的数据
[{
id: 1,
pid: 0,
path: '/admin/userList',
hidden: false,
name: 'admin',
icon: 'User',
title: '用户管理'
}, {
id: 2,
pid: 1,
name: 'user',
path: '/admin/userList',
title: '用户列表'
}, {
id: 2,
pid: 0,
name: 'system',
path: '/system/system',
hidden: true,
title: '系统管理'
}]
- 静态路由
import Layout from '@/layout/index.vue'
export default [{
path: '/login',
name: 'login',
component: () => import("@/views/Login.vue")
},
{
path: '/',
component: Layout,
name: 'Layout',
redirect: '/home/home',
children: [{
path: '/home/home',
name: 'home',
component: () => import("@/views/home/home.vue")
}]
},
{
path: '/:pathMatch(.*)*',
name: 'notFund',
component: () => import("@/views/notFund/notFund.vue")
}]
- permission.js
// import pinia from '../stores/piniaInstance'
import router from './index'
import { useLogin } from '@/stores/useLogin'
import { generatorRoute } from '../utils'
const LOGIN_PATH = '/login'
router.beforeEach((to, from) => {
let store = useLogin()
let menus = store.menus
let token = store.token
// 已登录,不是登录页面
if (token && to.path !== LOGIN_PATH) {
let hasRoute = menus.length > 0 && router.hasRoute(menus[0].name)
// 没有添加过路由
if (!hasRoute) {
let routes = generatorRoute(menus)
routes.forEach(it => {
router.addRoute("Layout", it)
})
router.replace(to.path)
}
} else if (token && to.path === LOGIN_PATH) {
// 已经登录,是登录页面
return { path: '/', replace: true }
} else if (!token && to.path !== LOGIN_PATH) {
// 没有登录,不是登录页面
return { path: LOGIN_PATH, replace: true }
}
})
标签:vue,return,vue3,router4,item,token,import,path,children
From: https://www.cnblogs.com/skystudy/p/17158718.html