话不多说,直接上代码,首先看看页面解构 (这里使用的是模拟import导入的数据):
路由文件:router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import dataList from '../assets/data' //模拟数据
import { defineAsyncComponent } from 'vue'
import { useCounterStore } from '@/stores/counter' // 引入 pinia库
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'shouye',
redirect: 'home'
},
{
path: '/home',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: () => import('../views/AboutView.vue')
}
]
})
// 前置路由守卫
router.beforeEach((to, from, next) => {
const useCounter = useCounterStore()
const nav = dataList.data.nav //获取到路由数据
// 方式1:通过pinia的confalse来判断是否是第一次加载页面,第一次的话,需要渲染路由和跳转到路径上的路由上,会执行两次
// if (useCounter.confalse) {
// routeCallback(nav)
// useCounter.$patch({
// count: nav,
// confalse: false
// })
// next({ path: to.path })
// } else {
// next() // 后面只要不刷新页面就会正常跳转路由
// }
//---------------------------------------------------------------------------------------------------------
// 方式二:首先加载路由,但是当前会多次加载路由
routeCallback(nav)
useCounter.$patch({
count: nav,
confalse: false
})
// 当前浏览页面数不少于0 或者 form的不等于 /
if (to.matched.length > 0 || from.path !== '/') {
next();
} else {
// 防止页面刷新 当上一次路由等于/ 并且 这次浏览记录为空的时候需要进入刷新前的页面
if (from.path == '/' && to.matched.length <= 0) {
next(to.path);
} else {
next('/404');
}
}
})
// 封装重复回调
function routeCallback(data: any) {
data.forEach((item: any) => {
if (item.children.length) {
routeCallback(item.children)
}
let route: any = {
name: item.name,
path: item.path,
meta: {
icon: item.icon,
title: item.title
},
component: (() => import(/* @vite-ignore */'../views/' + item.component + '.vue'))
// 如果报错了用这个 vite特别需要的引入
// component:()=> defineAsyncComponent(() => import(/* @vite-ignore */'../views/' + item.component + '.vue'))
}
router.addRoute(route)
})
}
export default router
pinia文件:stores/counter.ts
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref({})
const confalse = ref(true)
return { count, confalse }
})
pinia文件:stores/index.ts
import { createPinia } from 'pinia'
const pinia = createPinia()
export default pinia
main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import App from './App.vue'
import router from './router'
import pinia from './stores/index'
import './assets/main.css'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(router)
app.use(pinia)
app.use(ElementPlus)
app.mount('#app')
App.vue
Navigator One
item four
item one
{{item.title}}
{{item2.title}}
右侧视图
数据文件:assets/data.js
export default {
"code": 200,
"msg": "操作成功",
"data": {
"nav": [
{
"id": 1,
"title": "系统管理",
"icon": "el-icon-s-operation",
"path": "",
"name": "sys:manage",
"component": "",
"children": [
{
"id": 2,
"title": "用户管理",
"icon": "el-icon-s-custom",
"path": "/sys/users",
"name": "sys:user:list",
"component": "sys/User",
"children": [
{
"id": 9,
"title": "添加用户",
"icon": null,
"path": null,
"name": "sys:user:save",
"component": null,
"children": []
},
{
"id": 10,
"title": "修改用户",
"icon": null,
"path": null,
"name": "sys:user:update",
"component": null,
"children": []
},
{
"id": 11,
"title": "删除用户",
"icon": null,
"path": null,
"name": "sys:user:delete",
"component": null,
"children": []
},
{
"id": 12,
"title": "分配角色",
"icon": null,
"path": null,
"name": "sys:user:role",
"component": null,
"children": []
},
{
"id": 13,
"title": "重置密码",
"icon": null,
"path": null,
"name": "sys:user:repass",
"component": null,
"children": []
}
]
},
{
"id": 3,
"title": "角色管理",
"icon": "el-icon-rank",
"path": "/sys/roles",
"name": "sys:role:list",
"component": "sys/Role",
"children": [
{
"id": 7,
"title": "添加角色",
"icon": "",
"path": "",
"name": "sys:role:save",
"component": "",
"children": []
},
{
"id": 14,
"title": "修改角色",
"icon": null,
"path": null,
"name": "sys:role:update",
"component": null,
"children": []
},
{
"id": 15,
"title": "删除角色",
"icon": null,
"path": null,
"name": "sys:role:delete",
"component": null,
"children": []
},
{
"id": 16,
"title": "分配权限",
"icon": null,
"path": null,
"name": "sys:role:perm",
"component": null,
"children": []
}
]
},
{
"id": 4,
"title": "菜单管理",
"icon": "el-icon-menu",
"path": "/sys/menus",
"name": "sys:menu:list",
"component": "sys/Menu",
"children": [
{
"id": 17,
"title": "添加菜单",
"icon": null,
"path": null,
"name": "sys:menu:save",
"component": null,
"children": []
},
{
"id": 18,
"title": "修改菜单",
"icon": null,
"path": null,
"name": "sys:menu:update",
"component": null,
"children": []
},
{
"id": 19,
"title": "删除菜单",
"icon": null,
"path": null,
"name": "sys:menu:delete",
"component": null,
"children": []
}
]
}
]
},
{
"id": 5,
"title": "系统工具",
"icon": "el-icon-s-tools",
"path": "",
"name": "sys:tools",
"component": null,
"children": [
{
"id": 6,
"title": "数字字典",
"icon": "el-icon-s-order",
"path": "/sys/dicts",
"name": "sys:dict:list",
"component": "sys/Dict",
"children": []
}
]
},
{
"id": 20,
"title": "管理员",
"icon": null,
"path": null,
"name": "sys:user",
"component": "sys/Normal",
"children": []
}
],
"authoritys": [
"ROLE_admin",
"ROLE_normal",
"sys:manage",
"sys:user:list",
"sys:role:list",
"sys:menu:list",
"sys:tools",
"sys:dict:list",
"sys:role:save",
"sys:user:save",
"sys:user:update",
"sys:user:delete",
"sys:user:role",
"sys:user:repass",
"sys:role:update",
"sys:role:delete",
"sys:role:perm",
"sys:menu:save",
"sys:menu:update",
"sys:menu:delete",
"sys:user"
]
}
}
以上文件复制可直接形成一个demo,视图文件自己定义一下放个template就行了