Element-UI結(jié)合遞歸組件實現(xiàn)后臺管理系統(tǒng)左側(cè)菜單
在 Vue.js 中,允許你編寫一個組件來表示一個節(jié)點,而這個節(jié)點可以包含多個子節(jié)點,每個子節(jié)點又可以是同樣的組件。這種方式使得組件能夠處理無限層級的嵌套結(jié)構(gòu)。
應(yīng)用場景
遞歸組件非常適合處理具有層級結(jié)構(gòu)的數(shù)據(jù),以下是幾種常見的應(yīng)用場景:
- 多級菜單:如上所示,遞歸組件可以用來生成多級菜單,無論是水平還是垂直布局。
- 文件目錄樹:文件系統(tǒng)中的目錄結(jié)構(gòu)通常是樹狀的,遞歸組件可以幫助你輕松地構(gòu)建一個文件目錄樹。
- 評論系統(tǒng):許多網(wǎng)站的評論系統(tǒng)支持回復(fù)評論,形成一個樹形結(jié)構(gòu),遞歸組件可以用來展示這些評論及其回復(fù)。
- 組織架構(gòu)圖:公司內(nèi)部的組織結(jié)構(gòu)也可以用遞歸組件來表示,每個部門下面可以有子部門或員工。
- 任務(wù)列表:在項目管理工具中,任務(wù)列表往往包含父任務(wù)和子任務(wù),遞歸組件可以清晰地展現(xiàn)這種層次關(guān)系。
實現(xiàn)步驟
1. 安裝 Element-UI
確保你的項目已經(jīng)安裝了 Element-UI。如果還沒有安裝,可以通過 npm 或 yarn 來安裝:
npm install element-ui --save # 或者 yarn add element-ui
然后在 main.js 文件中引入并使用 Element-UI:
import Vue from 'vue'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);
2. 設(shè)計菜單數(shù)據(jù)結(jié)構(gòu)
先定義一個合理的菜單數(shù)據(jù)結(jié)構(gòu),通常是一個數(shù)組對象,其中每個對象代表一個菜單項,并且可以包含子菜單。例如:
import Layout from '@/Layout/index.vue' export const routes = [ { path: '/', name: 'redirect', component: Layout, hidden: true, // 隱藏菜單 redirect: "/homePage", // 用戶在地址欄輸入 '/' 時會自動重定向到 /homePage 頁面 }, { path: '/homePage', component: Layout, redirect: "/homePage/index", meta: { title: "首頁", }, children: [ { path: 'index', name: 'homePageIndex', meta: { title: "首頁", }, component: () => import('@/views/homePage/index.vue') } ] }, { path: '/login', component: () => import('@/views/login.vue'), hidden: true }, { path: '/404', component: () => import('@/views/error/404.vue'), hidden: true }, { path: '/401', component: () => import('@/views/error/401.vue'), hidden: true }, { path: '/admin', meta: { title: "系統(tǒng)管理", }, component: Layout, children: [ { path: 'user', name: 'userIndex', meta: { title: "用戶管理", }, component: () => import('@/views/admin/user.vue') }, { path: 'role', name: 'roleIndex', meta: { title: "權(quán)限管理", }, component: () => import('@/views/admin/role.vue'), children: [ { path: 'add', name: 'addRole', hidden: true, meta: { title: "添加角色", }, component: () => import('@/views/admin/user/index.vue') }, { path: 'update', name: 'updateRole', hidden: true, meta: { title: "編輯角色", }, component: () => import('@/views/admin/role/index.vue') } ] } ] }, { path: '/tableEcho', meta: { title: "表格管理", }, component: Layout, children: [ { path: 'test', name: 'tableEchoIndex', meta: { title: "表格測試", }, component: () => import('@/views/tableEcho/index.vue'), children: [ { path: 'add', name: 'addTable', hidden: true, meta: { title: "新增測試", }, component: () => import('@/views/tableEcho/add.vue') } ] }, ], }, ]
上述示例:
- 配置了四個路由器:根路徑重定向、首頁、系統(tǒng)管理、表格管理。
- 根路徑重定向: 訪問根路徑
'/'
時,會自動重定向到/homePage
。 - 首頁菜單: 一個子菜單。
- 系統(tǒng)管理: 兩個子菜單, 兩個三級菜單(不展示)。
- 表格管理: 一個子菜單, 一個三級菜單(不展示)。
注意點:
每個菜單的一級路由的
component
都必須是Layout
組件,Layout
組件用于定義整個系統(tǒng)頁面的基本結(jié)構(gòu)和布局,比如導(dǎo)航欄、側(cè)邊欄等。通過將所有的一級路由都指向Layout
組件,可以確保無論用戶訪問哪個頁面,都能看到一致的布局。
Layout 組件文件布局圖片如下
3. 創(chuàng)建遞歸組件
創(chuàng)建一個遞歸組件來渲染菜單項。這個組件將根據(jù)傳入的數(shù)據(jù)結(jié)構(gòu)遞歸地生成菜單項。
Sidebar / SidebarItem.vue
<div class="sidebar_item"> <!-- 如果沒有子菜單或只有一個二級的子菜單則直接渲染 --> <template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren)" class="item"> <router-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"> <el-menu-item :index="resolvePath(onlyOneChild.path)" class="title"> <img src="" alt=""> <span slot="title">{{ onlyOneChild.meta.title }}</span> </el-menu-item> </router-link> </template> <!-- 有子菜單 --> <el-submenu v-else :index="resolvePath(item.path)" popper-append-to-body> <template slot="title"> <span slot="title" class="title">{{ item.meta.title }}</span> </template> <Sidebar-item v-for="child in item.children" :key="child.path" :is-nest="true" :item="child" :base-path="resolvePath(child.path)"></Sidebar-item> </el-submenu> </div> </template> <script> import path from "path"; export default { name: "SidebarItem", data() { return { onlyOneChild: { children: [], }, } }, props: { item: { type: Object, required: true }, basePath: { type: String, default: '' } }, methods: { // 判斷是否只有一個子菜單 hasOneShowingChild(children = [], parent) { // console.log('parent::: ',children , parent); if (!children) { children = []; } // 過濾掉隱藏的菜單 const showingChildren = children.filter((item) => { // 是否隱藏菜單 if (item.hidden) { return false; } else { this.onlyOneChild = item; return true; } }); // 當(dāng)只有一個子路由時,默認(rèn)顯示子路由器 if (showingChildren.length === 1) { return true; } // 如果沒有子路由,則顯示父級路由 if (showingChildren.length === 0) { this.onlyOneChild = { ...parent, path: "", noShowingChildren: true }; return true; } return false; }, // 判斷是否是外鏈 isExternal(path) { return /^(https?:|mailto:|tel:)/.test(path); }, // 路徑拼接 resolvePath(routePath) { if (this.isExternal(routePath)) { return routePath; } if (this.isExternal(this.basePath)) { return this.basePath; } return path.resolve(this.basePath, routePath); }, } } </script> <style lang="scss" scoped> .sidebar_item { cursor: pointer; >a { height: 60px; line-height: 60px; } } ::v-deep .el-submenu__title { height: 60px; line-height: 60px; } ::v-deep .el-submenu__title:hover, a :hover { background-color: #2a9cff !important; } ::v-deep .active { background-color: #2a9cff !important; } .is-active { background-color: #2a9cff !important; } .title { font-size: 16px; } </style>
注意:
代碼里導(dǎo)入的
path
模塊需要安裝 node-polyfill-webpack-plugin 模塊, 原因是由于 webpack5 中移除了nodejs
核心模塊的polyfill
自動引入, 所以需要下載插件手動引入
npm install node-polyfill-webpack-plugin --save # 或者 yarn add node-polyfill-webpack-plugin
vue.config.js 配置
const { defineConfig } = require('@vue/cli-service'); const nodePolyfillWebpackPlugin = require("node-polyfill-webpack-plugin"); module.exports = defineConfig({ configureWebpack: (config) => { // 由于webpack5中移除了nodejs核心模塊的polyfill自動引入, 所以需要下載插件手動引入 config.plugins.push(new nodePolyfillWebpackPlugin()); } })
4. 使用遞歸組件
在主布局或需要顯示菜單的地方使用 Menu 組件,并傳遞菜單數(shù)據(jù):
Sidebar / index.vue
<template> <div style="padding-top: 30px;"> <!-- 左側(cè)菜單 --> <el-menu :default-active="index" class="memu" @open="handleOpen" @close="handleClose" background-color="#304156" text-color="#bfcbd9" active-text-color="#fff" @select="handleSelect"> <Sidebar-item v-for="route in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" /> </el-menu> </div> </template> <script> import SidebarItem from './SidebarItem.vue'; import { mapGetters } from "vuex"; export default { name: 'Sidebar', data() { return { index: this.$route.path, } }, components: { SidebarItem }, computed: { ...mapGetters(["sidebarRouters"]), }, methods: { handleOpen(key, keyPath) { console.log('handleOpen::: ', key, keyPath); }, handleClose(key, keyPath) { console.log('handleClose::: ', key, keyPath); }, handleSelect(index, indexPath) { console.log('handleSelect::: ', index, indexPath); } } } </script> <style lang="scss" scoped> .memu { display: inline-block; text-align: left; width: 100%; } </style>
實現(xiàn)效果
總結(jié)
Element-UI 結(jié)合遞歸組件的方式,用于構(gòu)建后臺管理系統(tǒng)的左側(cè)菜單,主要是通過以下步驟實現(xiàn)的:
配置路由(Routes): 首先,如同前述代碼片段所示,定義一系列路由對象構(gòu)成的數(shù)組 routes,這些對象不僅描述了各頁面路徑(path)、頁面名稱(name)、對應(yīng)組件(component),還包括了嵌套的子路由(children)以及元信息(如頁面標(biāo)題)等,從而形成了多級菜單的結(jié)構(gòu)基礎(chǔ)。
遞歸組件(Recursive Component): 利用 Vue 中的遞歸組件技術(shù),創(chuàng)建一個菜單組件,該組件根據(jù)傳入的路由配置(通常是 routes 數(shù)組)自動生成菜單項。遞歸的邏輯在于:組件內(nèi)根據(jù)當(dāng)前路由的 children 屬性判斷是否有子菜單,如果有,則繼續(xù)渲染子菜單組件,直至沒有更多子節(jié)點,以此實現(xiàn)無限級菜單的展現(xiàn)。
Element-UI 風(fēng)格: 在實現(xiàn)遞歸菜單組件時,利用 Element-UI 的 UI 組件庫(如 el-menu、el-submenu、el-menu-item 等),為菜單項賦予統(tǒng)一且美觀的樣式,實現(xiàn)折疊、展開、激活狀態(tài)等交互效果,增強(qiáng)用戶體驗。
總結(jié)而言,Element-UI 與遞歸組件結(jié)合的方式,使得后臺管理系統(tǒng)的左側(cè)菜單能夠高效地根據(jù)路由配置動態(tài)渲染多層級菜單,同時確保了菜單的一致性和美觀性,提升了系統(tǒng)的可維護(hù)性和用戶體驗。
到此這篇關(guān)于Elemnt-UI + 遞歸組件實現(xiàn)后臺管理系統(tǒng)左側(cè)菜單的文章就介紹到這了,更多相關(guān)Elemnt-UI + 遞歸組件實現(xiàn)后臺管理系統(tǒng)左側(cè)菜單內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue之保留小數(shù)點兩位小數(shù) 使用filters(過濾器)
這篇文章主要介紹了vue之保留小數(shù)點兩位小數(shù) 使用filters(過濾器),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11Vue封裝DateRangePicker組件流程詳細(xì)介紹
在后端管理項目中使用vue來進(jìn)行前端項目的開發(fā),但我們都知道Vue實際上無法監(jiān)聽由第三方插件所引起的數(shù)據(jù)變化。也無法獲得JQuery這樣的js框架對元素值的修改的。而日期控件daterangepicker又基于JQuery來實現(xiàn)的2022-11-11elementUI el-form 數(shù)據(jù)無法賦值且不報錯解決方法
本文主要介紹了elementUI el-form 數(shù)據(jù)無法賦值且不報錯解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12詳解Vue返回值動態(tài)生成表單及提交數(shù)據(jù)的辦法
這篇文章主要為大家介紹了Vue返回值動態(tài)生成表單及提交數(shù)據(jù),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2021-12-12