之前把注入路由写在beforeEach里面,在搭建动态路由前出现了很多问题,尝试各种方法都不行,心都累了。网上基本上都是这样方式,不能这样搞,反正我的项目是实现不了的。
不知道出现多少错误,比如,无法找到文件、import引入错误。
Uncaught (in promise) Error: Cannot find module './() => webpack_require("./src/views lazy recursive ^) /.* " ) ( . / ")(~./ ")( ./(templode.component]~)
部分错误代码如下:
几经磨砺,用了很多方法,搞了好几次。最后换了一种写法,才弄出来。
vue/cli版本如下,基本上是目前最新版本。
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-typescript": "~5.0.0",
"@vue/cli-service": "~5.0.0",
真正能实现的代码,正确代码,如下!!!!!!!!!!!!!!!
实现:两个文件代码menu.ts、router/index.ts
1. menu.ts
export const menuData: any = [
{
id: 11,
parent_id: 1,
name: 'about',
path: '/about',
component: 'About.vue',
meta: { title: '关于我们', type: 'type_menu', redirect_path: '' }
},
{
id: 12,
parent_id: 1,
name: 'form',
path: '/form',
component: 'form/index.vue',
meta: { title: '主页', type: 'type_menu', redirect_path: '' },
children: [
{
id: 13,
parent_id: 12,
name: 'child',
path: '/child',
component: 'form/child/index.vue',
meta: { title: '日历', type: 'type_menu', redirect_path: '' }
}
]
}
]
2. router/index.ts代码如下
方式一:有登录,在beforeEach中注入路由。
菜单都扁平化了,测试中菜单有children就会报错,把children全部去掉了。
关键点:在beforeEach中注入路由后,一定要next(to.fullPath)
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Layout from '@/layout/index.vue'
import { cookie, storage } from '@/utils/tool'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Layout',
component: Layout,
redirect: '/workBench',
children: [
{
path: '/workBench',
name: 'workBench',
component: () => import(/* webpackChunkName: "workBench" */ '../views/workBench/index.vue')
}
]
},
{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "login" */ '@/views/login/index.vue')
},
{
path: '/:pathMatch(.*)*',
component: () => import(/* webpackChunkName: "404" */ '@/layout/other/404.vue')
}
]
// 菜单扁平化
const flattenMenu = (menu: any) => {
let result: any = []
for (let i = 0; i < menu.length; i++) {
const data = {
name: menu[i].name,
path: menu[i].path,
component: () => import(`@/views/${menu[i].component}`)
}
result.push(data)
if (Array.isArray(menu[i].children)) {
result = result.concat(flattenMenu(menu[i].children))
}
}
return result
}
const router = createRouter({
history: createWebHistory(),
routes
})
let isFlag = false
const token = cookie.get('TOKEN')
router.beforeEach(async (to, from, next) => {
if (to.path === '/login') {
cookie.remove('TOKEN')
storage.removeItem('MENU')
next()
return
}
if (token) {
if (!isFlag) {
isFlag = true
const menuData: any = storage.getItem('MENU') || []
const menuList = flattenMenu(menuData)
menuList.forEach((element: any) => {
router.addRoute('Layout', element)
})
next(to.fullPath)
} else {
next()
}
} else {
next({ path: '/login' })
}
})
export default router
方式二:无登录
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import { menuData } from './menu'
import Layout from '@/layout/index.vue'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Layout',
component: Layout,
redirect: '/workBench',
children: [
{
path: '/workBench',
name: 'workBench',
component: () => import(/* webpackChunkName: "workBench" */ '../views/workBench/index.vue')
}
]
},
{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "login" */ '@/views/login/index.vue')
},
{
path: '/:pathMatch(.*)*',
component: () => import(/* webpackChunkName: "404" */ '@/layout/other/404.vue')
}
]
// childType是我项目需要判断菜单为一级添加layout布局
function addRoutes (routes: RouteRecordRaw[], menu: any[], childType?: string) {
for (const item of menu) {
let route: any = {}
if (childType) {
route = {
path: item.path,
name: item.name,
component: () => import(`@/views/${item.component}`),
meta: item.meta
}
} else {
route = {
path: item.path,
name: item.name,
component: Layout,
meta: item.meta,
children: [
{
path: '',
component: () => import(`@/views/${item.component}`)
}
]
}
}
if (item.children) {
route.children = []
addRoutes(route.children, item.children, 'child')
}
routes.push(route)
}
}
// 注入路由
addRoutes(routes, menuData)
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
End~~~~~~~