系列文章目录
- 系列介绍:Vue3 + Vite + TS 从零开始学习
- 项目搭建:(一) Vue3 + Vite + TS 项目搭建
- 实现动态菜单栏:(二) Vue3 + Element-Plus 实现动态菜单栏
- 实现动态面包屑:(三) Vue3 + Element-Plus 实现动态面包屑
- 实现动态标签页:(四) Vue3 + Element-Plus 实现动态标签页
- 实现动态主题色切换(demo):(五) Vue3 + Element-Plus 实现动态主题色切换
- 踩坑记录(持续更新):(六) Vue3 踩坑记录
文章目录
一、引入依赖
开始前请确保已经安装以下依赖:
- VueX
$ npm i vuex --save
- Vue-Router
$ npm i vue-router --save
- NProgress
$ npm i nprogress --save
二、目录结构
|-src -- 主目录
---|api -- Ajax请求统一存放目录
------|auth-api.js -- 路由数据获取接口
---|js --JS脚本
------|permission.js -- NProgress进度条数据处理
---|layout -- 页面布局组件
------|sidebar.vue -- 侧边栏布局组件
---|store -- VueX
------|router.js -- 路由全局常量
三、核心代码
1. auth-api.js
import request from'@/js/request'exportdefault{routers(data){return request.post('/routers', data)}}
2. permission.js
import router from'../router'import store from'../store'import NProgress from'nprogress'import'nprogress/nprogress.css'import{ getCookie }from'./cookie'import Layout from'../layout/index.vue'import ParentView from'../components/ParentView/index.vue'
NProgress.configure({showSpinner:false})const whiteList =['/login','/register']
router.beforeEach((to, from, next)=>{
NProgress.start()if(getCookie()){if(to.path ==='/login'){next({path:'/'})
NProgress.done()}else{if(store.state.user.menus.length ===0){
store.dispatch('GetInfo').then(res=>{const menuIds = res.data.menuIds
store.dispatch('GenerateRoutes', menuIds).then(routes=>{filterRoutes(routes)
routes.forEach(route=>{
router.addRoute(route)})next({...to,replace:true})})}).catch(()=>{next()})}else{next()}}}else{if(whiteList.indexOf(to.path)!==-1){next()}else{next(`/login?redirect=${to.fullPath}`)
NProgress.done()}}})
router.afterEach(()=>{
NProgress.done()})constfilterRoutes=(routes)=>{const accessRoutes = routes.filter(route=>{let modules =import.meta.glob('../views/**/*.vue')if(route.component){if(route.component ==='ParentView'){
route.component = ParentView
}elseif(route.component ==='Layout'){
route.component = Layout
}else{
route.component = modules[`../views/${route.component}.vue`]}}if(route.children && route.children.length){filterRoutes(route.children)}returntrue})return accessRoutes
}
3.sidebar.vue
<template><el-aside width="210px"class="aside-wrapper"><el-scrollbar><el-menu :default-active="route.path" mode="vertical":collapse-transition="false" router class="menu-wrapper"><el-sub-menu v-for="menu in menus":key="menu.path":index="menu.path"><template #title><el-icon><component :is="menu.meta.icon"/></el-icon><span>{{ menu.name }}</span></template><el-menu-item v-for="child in menu.children":key="child.path":index="child.path"><template #title><el-icon><component :is="child.meta.icon"/></el-icon><span>{{ child.name }}</span></template></el-menu-item></el-sub-menu></el-menu></el-scrollbar></el-aside></template><script lang="ts" setup>import{ computed }from'vue'import{ useStore }from'vuex'import{ useRoute }from'vue-router'const store =useStore()const route =useRoute()const menus = store.state.router.accessRoutes
</script>
4.router.js
import{ authApi }from'@/api'import constantRoutes from'@/router/routes'const router ={state:{routes:[],accessRoutes:[]},mutations:{SET_ROUTES:(state, routes)=>{
state.routes = routes
},SET_ACCESSROUTES:(state, accessRoutes)=>{
state.accessRoutes = accessRoutes
}},actions:{GenerateRoutes({ commit }, roleIds){returnnewPromise(resolve=>{
authApi.routers(roleIds).then(res=>{const accessRoutes = res.data
filterRoutes('', accessRoutes)const routes = constantRoutes.concat(accessRoutes)commit('SET_ROUTES', routes)commit('SET_ACCESSROUTES', accessRoutes)resolve(routes)})})}}}constfilterRoutes=(path, routes)=>{
routes.forEach(route=>{const routePath = route.path
if(route.parentId !=='0'){
route.path = path +"/"+ routePath
}if(route.children && route.children.length){filterRoutes(routePath, route.children)}})}exportdefault router
四、最终效果
本文转载自: https://blog.csdn.net/Bao59/article/details/128763826
版权归原作者 下辈子不当程序猿 所有, 如有侵权,请联系我们删除。
版权归原作者 下辈子不当程序猿 所有, 如有侵权,请联系我们删除。