Vue3 根據(jù)路由動(dòng)態(tài)生成側(cè)邊菜單的方法
在 Vue3 的項(xiàng)目開(kāi)發(fā),尤其是后臺(tái)管理系統(tǒng)這類(lèi)復(fù)雜應(yīng)用場(chǎng)景中,側(cè)邊菜單扮演著舉足輕重的角色,它是用戶快速導(dǎo)航至各個(gè)功能模塊的得力助手。而根據(jù)路由動(dòng)態(tài)生成側(cè)邊菜單,則為系統(tǒng)的靈活性和可擴(kuò)展性增添了強(qiáng)大動(dòng)力。接下來(lái),我們將深入探討如何在 Vue3 中實(shí)現(xiàn)這一關(guān)鍵功能。
gitCode代碼地址:https://gitcode.com/Jiaberrr/vue3-pc-template/overview,
gitee代碼地址:https://gitee.com/zunyi-gabe/vue3-pc-template (如果需要簡(jiǎn)單版(除了框架啥也沒(méi)有)請(qǐng)切到master分支)
演示地址1:https://vue3-pc-template.vercel.app/login演示地址2:https://env-00jxt0stsnl3-static.normal.cloudstatic.cn/index.html
一、準(zhǔn)備工作
首先,確保你的 Vue3 項(xiàng)目已經(jīng)集成了 Vue Router 和合適的 UI 組件庫(kù)(如 Element Plus,這里以其為例進(jìn)行講解,原理相通)。Vue Router 負(fù)責(zé)管理路由信息,而 UI 組件庫(kù)則提供了美觀且功能豐富的菜單組件供我們使用。
二、路由配置基礎(chǔ)
在項(xiàng)目的路由模塊(通常是 router/index.js 之類(lèi)的文件)中,精心定義好各個(gè)路由路徑及其對(duì)應(yīng)的組件。例如:
import { createRouter, createWebHistory } from 'vue-router'; import Home from '@/views/Home.vue'; import About from '@/views/About.vue'; import UserManage from '@/views/UserManage.vue'; const routes = [ { path: '/', name: 'Home', component: Home, meta: { breadcrumbName: '首頁(yè)', icon: 'HomeFilled' // 假設(shè) Element Plus 的圖標(biāo)名稱(chēng),實(shí)際依庫(kù)而定 } }, { path: '/about', name: 'About', component: About, meta: { breadcrumbName: '關(guān)于我們', icon: 'InfoFilled' } }, { path: '/user-manage', name: 'UserManage', component: UserManage, meta: { breadcrumbName: '用戶管理', icon: 'UserFilled' }, children: [ { path: 'list', name: 'UserList', component: () => import('@/views/UserList.vue'), meta: { breadcrumbName: '用戶列表' } }, { path: 'add', name: 'UserAdd', component: () => import('@/views/UserAdd.vue'), meta: { breadcrumbName: '添加用戶' } } ] } ]; const router = createRouter({ history: createWebHistory(), routes }); export default router;
這里,每個(gè)路由對(duì)象都有 meta 字段,用于存儲(chǔ)菜單顯示相關(guān)的額外信息,如面包屑名稱(chēng)和圖標(biāo)名稱(chēng),同時(shí)部分路由設(shè)置了子路由,構(gòu)建出層級(jí)結(jié)構(gòu),為側(cè)邊菜單的多級(jí)展示奠定基礎(chǔ)。
三、組件搭建
創(chuàng)建側(cè)邊菜單組件(例如 SidebarMenu.vue):
<template> <div class="logo-container flex-center"> <img class="logo-icon" src="/img/logo.png" /> <text v-if="!isCollapse">后臺(tái)管理平臺(tái)</text> </div> <el-menu :default-active="$route.path" class="el-menu-vertical-demo" router unique-opened :collapse="isCollapse" @select="changeMenu" > <el-menu-item index="/dashboard"> <el-icon><Menu /></el-icon> <template #title>首頁(yè)</template> </el-menu-item> <el-sub-menu v-for="item in routerList" :index="item.path" :key="item.name"> <template #title> <el-icon> <component :is="item.meta.icon" /> </el-icon> <span v-show="!isCollapse"> {{ item.meta.breadcrumbName }} </span> </template> <el-menu-item v-for="ite in item.children" :index="item.path+ '/'+ ite.path" :key="ite.name" >{{ ite.meta.breadcrumbName }}</el-menu-item > </el-sub-menu> </el-menu> </template> <script setup> import router from "@/router"; import { useAuthRouterStore } from "@/stores/authRouter.js"; import { useTagStore } from "@/stores/tagList.js"; const tagStore = useTagStore(); const routerOptions = router.getRoutes() const authRouterStore = useAuthRouterStore(); const props = defineProps(["isCollapse"]); const routerList = authRouterStore.routerList; const changeMenu = (menu) => { let obj = routerOptions.find(val => val.path == menu) tagStore.addTagList({ name:obj.path, breadcrumbName:obj.meta.breadcrumbName }) } </script> <style scoped> .el-menu-vertical-demo:not(.el-menu--collapse) { width: 180; } .logo-container { width: 100%; height: 60px; overflow: hidden; } .logo-icon { height: 60px; scale: 1.4; } </style>
在模板部分:
1、頭部 logo 展示:
通過(guò)<div class="logo-container flex-center">包裹,實(shí)現(xiàn)了 logo 圖標(biāo)和平臺(tái)名稱(chēng)的水平居中布局。當(dāng)側(cè)邊欄處于展開(kāi)狀態(tài)(!isCollapse)時(shí),顯示“后臺(tái)管理平臺(tái)”文字,logo 圖標(biāo)通過(guò)<img class="logo-icon" src="/img/logo.png" />引入,并且設(shè)置了一定的樣式,如高度為 60px,縮放比例為 1.4。
2、 菜單主體構(gòu)建:
- 使用了 Element UI 的 <el-menu> 組件來(lái)構(gòu)建側(cè)邊菜單。
- :default-active="$route.path":將當(dāng)前激活菜單與當(dāng)前路由路徑綁定,確保用戶在頁(yè)面跳轉(zhuǎn)時(shí),對(duì)應(yīng)的菜單能正確高亮顯示。
- router 屬性開(kāi)啟了路由模式,使得點(diǎn)擊菜單能夠自動(dòng)觸發(fā)路由跳轉(zhuǎn)。
- unique-opened 保證了同一時(shí)間只有一個(gè)子菜單處于展開(kāi)狀態(tài),提升了菜單的交互體驗(yàn)。
- :collapse="isCollapse":用于控制菜單的折疊狀態(tài),根據(jù)傳入的 isCollapse 屬性值來(lái)決定菜單是否折疊顯示。
- @select="changeMenu":綁定了菜單選擇事件,當(dāng)用戶點(diǎn)擊菜單時(shí),會(huì)觸發(fā) changeMenu 方法,后續(xù)我們?cè)僭敿?xì)講解這個(gè)方法的作用。
- 菜單分為兩級(jí)結(jié)構(gòu):
一級(jí)菜單:<el-menu-item index="/dashboard"> 代表首頁(yè)菜單,有對(duì)應(yīng)的圖標(biāo)<el-icon><Menu /></el-icon>和標(biāo)題<template #title>首頁(yè)</template>。
二級(jí)菜單:通過(guò) v-for 循環(huán)遍歷 routerList 數(shù)組來(lái)生成。每個(gè)二級(jí)菜單組由 <el-sub-menu> 包裹,標(biāo)題部分同樣有圖標(biāo)和名稱(chēng)顯示,子菜單項(xiàng)通過(guò)內(nèi)層的 v-for 循環(huán) item.children 生成,每個(gè)子菜單項(xiàng)的 index 由父級(jí)路徑和自身路徑拼接而成,確保路由的準(zhǔn)確性,并且展示對(duì)應(yīng)的 breadcrumbName 作為菜單名稱(chēng)。
在腳本部分:
1、 模塊引入:
- 引入了項(xiàng)目的路由實(shí)例 router,這是 Vue Router 在項(xiàng)目中的核心模塊,用于管理路由相關(guān)操作。
- 引入了兩個(gè)自定義的 Vuex 存儲(chǔ)模塊:useAuthRouterStore 和 useTagStore,分別用于管理認(rèn)證相關(guān)的路由信息和標(biāo)簽列表信息。實(shí)例化 tagStore 和 authRouterStore 以便后續(xù)使用。
2、 組件屬性接收:
- 通過(guò) defineProps(["isCollapse"]) 接收父組件傳入的 isCollapse 屬性,用于控制菜單的折疊狀態(tài),與模板中的 :collapse="isCollapse" 相對(duì)應(yīng)。
3、 數(shù)據(jù)獲取與方法定義:
- routerList = authRouterStore.routerList:從 authRouterStore 中獲取路由列表數(shù)據(jù),這個(gè)數(shù)據(jù)應(yīng)該是經(jīng)過(guò)權(quán)限過(guò)濾等處理后的動(dòng)態(tài)路由列表,用于在模板中生成側(cè)邊菜單。
- changeMenu 方法:當(dāng)菜單被點(diǎn)擊時(shí)觸發(fā)。它首先在 routerOptions(通過(guò) router.getRoutes() 獲取的所有路由配置信息)中查找與當(dāng)前點(diǎn)擊菜單 menu 對(duì)應(yīng)的路由對(duì)象 obj。然后,調(diào)用 tagStore.addTagList 方法,向標(biāo)簽列表存儲(chǔ)中添加一個(gè)新的標(biāo)簽對(duì)象,包含當(dāng)前點(diǎn)擊菜單對(duì)應(yīng)的路由路徑 name:obj.path 和面包屑名稱(chēng) breadcrumbName:obj.meta.breadcrumbName,這一步可能是用于記錄用戶的操作歷史或者構(gòu)建面包屑導(dǎo)航等功能。
四、優(yōu)化與拓展
1、 權(quán)限控制:結(jié)合后端返回的用戶權(quán)限信息,在 filteredRoutes 計(jì)算屬性中進(jìn)一步篩選,確保用戶只能看到有權(quán)訪問(wèn)的菜單。例如,可以在路由的 meta 字段添加權(quán)限標(biāo)識(shí),然后根據(jù)用戶的權(quán)限列表進(jìn)行比對(duì)過(guò)濾。
2、 動(dòng)態(tài)加載菜單:對(duì)于大型項(xiàng)目,一次性加載所有菜單可能影響初始加載性能??梢岳?Vue 的異步組件特性,在用戶點(diǎn)擊展開(kāi)二級(jí)菜單或者進(jìn)入特定模塊時(shí),再動(dòng)態(tài)加載子菜單對(duì)應(yīng)的組件,優(yōu)化資源利用。
3、 樣式定制:根據(jù)項(xiàng)目的設(shè)計(jì)風(fēng)格,深入定制側(cè)邊菜單的樣式,如顏色、字體、動(dòng)畫(huà)效果等,提升用戶視覺(jué)體驗(yàn)。
通過(guò)以上步驟,我們?cè)?Vue3 中成功構(gòu)建了一個(gè)根據(jù)路由動(dòng)態(tài)生成的側(cè)邊菜單系統(tǒng),并且為后續(xù)的功能拓展和優(yōu)化鋪就了堅(jiān)實(shí)道路,助力打造高效、易用的 Vue3 應(yīng)用。
到此這篇關(guān)于Vue3 中如何根據(jù)路由動(dòng)態(tài)生成側(cè)邊菜單的文章就介紹到這了,更多相關(guān)vue3路由動(dòng)態(tài)生成側(cè)邊菜單內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
echarts 使用formatter 修改鼠標(biāo)懸浮事件信息操作
這篇文章主要介紹了echarts 使用formatter 修改鼠標(biāo)懸浮事件信息操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07vue.set() (this.$set)的用法及說(shuō)明
這篇文章主要介紹了vue.set() (this.$set)的用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06vue3+ts中ref與reactive指定類(lèi)型實(shí)現(xiàn)示例
這篇文章主要為大家介紹了vue3+ts中ref及reactive如何指定類(lèi)型的實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06vue項(xiàng)目中跳轉(zhuǎn)到外部鏈接的實(shí)例講解
今天小編就為大家分享一篇vue項(xiàng)目中跳轉(zhuǎn)到外部鏈接的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue實(shí)現(xiàn)點(diǎn)擊按鈕下載文件功能
這篇文章主要介紹了vue中點(diǎn)擊按鈕下載文件,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-10-10Element-ui中的Cascader級(jí)聯(lián)選擇器基礎(chǔ)用法
這篇文章主要為大家介紹了Element-ui中的Cascader級(jí)聯(lián)選擇器基礎(chǔ)用法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06vscode中eslint配置保存自動(dòng)修復(fù)代碼示例詳解
vscode根據(jù)eslint保存?動(dòng)修復(fù)配置,下面這篇文章主要給大家介紹了關(guān)于vscode中eslint配置保存自動(dòng)修復(fù)代碼的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12