vue3 +vite 动态菜单和路由懒加载
当前项目是根据vue-element-admin使用vue3重构的后台管理系统从后台获取动态菜单并且路由懒加载后台返回的数据结构"code": 0,"msg": "成功","data": [{"path": "/administrator","meta": {"title": "后台管理","icon": "icon-a-zu4","roles": ["admin"
·
当前项目是根据vue-element-admin
使用vite+vue3重构的后台管理系统
从后台获取动态菜单并且路由懒加载
后台返回的数据结构
"code": 0,
"msg": "成功",
"data": [
{
"path": "/administrator",
"meta": {
"title": "后台管理",
"icon": "icon-a-zu4",
"roles": [
"admin"
]
},
"children": [
{
"path": "admin",
"meta": {
"title": "管理员",
"roles": [
"admin"
]
},
"component": "views/administrator/admin"
},
{
"path": "role",
"meta": {
"title": "角色",
"roles": [
"admin"
]
},
"component": "views/administrator/role"
},
{
"path": "auth",
"meta": {
"title": "权限",
"roles": [
"admin"
]
},
"component": "views/administrator/auth"
}
],
"component": "Layout",
"redirect": "/administrator/admin",
"alwaysShow": true
}
]
}
src/permission.js
请求菜单信息
const accessRoutes = await store.dispatch('permission/generateRoutes') // 获取当前用户的菜单信息
store/modules/permission.js
将之前的前端写死的路由改成去后台请求对应的菜单
const actions = {
generateRoutes({ commit }) {
return new Promise(resolve => {
menu({username: storage.getItem('username')}).then((response) => {
let accessedRoutes = filterAsyncRoutes(response.data)
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
})
}
}
store/modules/permission.js
添加地址 菜单过滤 生成对应的菜单
export function filterAsyncRoutes(routes) {
const async = routes.filter(route => {
if(route.component){
route.component = Layout
if(route.children && route.children.length){
route.children.forEach(item => {
item.component = loadView(item.component)
})
return true
}
return true
}
return true
})
console.log(async)
return async
}
/**
* 路由懒加载 拼接
* @param view
* @returns {function(): *}
*/
export const loadView = (view) => {
// 这里需要注意一下 vite+vue3 要用 defineAsyncComponent 才能拼接成功 不然会一直报错找不到模块 加上/* @vite-ignore */ 可以不显示警告
return () => defineAsyncComponent(() => import(/* @vite-ignore */`/src/${view}.vue`))
}
store/modules/permission.js
将不需要权限的路由过滤
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
// 过滤掉不需要显示在菜单栏的公共菜单 并格式化
let constant = filterConstantRoutes(constantRoutes)
state.routes = constant.concat(routes)
}
}
/**
* 过滤递归公共路由
* @param routes
* @returns {*[]}
*/
export function filterConstantRoutes(routes){
const router = routes.filter( item => !item.hidden )
const routeList = []
for (const item of router) {
let temp = {}
if (!item.alwaysShow && item.children.length) {
temp.path = item.path
temp.meta = item.children[0].meta
temp.alwaysShow = false
routeList.push(temp)
} else {
routeList.push(item)
}
}
return routeList
}
直接在菜单界面遍历出来就可以显示成功
注意:后台的数据结构,不要写错了
loadView 的地方很容易搞错,vue2和vue3的写法是不一样,js和ts的写法也不一样
更多推荐
已为社区贡献6条内容
所有评论(0)