vue3+Element采用遞歸調(diào)用封裝導(dǎo)航欄實(shí)現(xiàn)
效果預(yù)覽
模擬數(shù)據(jù)
- 數(shù)據(jù)來源有很多,可以是自己寫死的,也可以是后端調(diào)用得到的,也可以從別的組件中拿到
- 這里采用從路由中拿
- 定義數(shù)據(jù)源src/router/module.js/
const Login = () => import('../views/Login/Login.vue'); const Layout = () => import('../layout/layout.vue'); const Home = () => import('../views/Home.vue'); const User = () => import('../views/About.vue'); const Avatar = () => import('../views/Users/Avatar.vue'); const Password = () => import('../views/Users/Password.vue'); const routes = [ { path: '/', redirect: '/home', }, { path: '/', name: 'Layout', component: Layout, meta: { permission: true, }, children: [ { path: '/home', name: 'Home', component: Home, meta: { title: '首頁', icon: '<span class="iconfont icon-shouye"/>', // iconfont圖標(biāo) inSide: true, }, }, { path: '/user', name: 'User', component: User, meta: { title: '個(gè)人中心', icon: '<span class="iconfont icon-yonghuzhongxin1"/>', }, children: [ { path: '/user/avatar', name: 'Avatar', component: Avatar, meta: { title: '修改頭像', }, children: [ { path: '/setUp/avatar', name: 'setUp', component: Avatar, meta: { title: '暫無', }, }, ], }, { path: '/user/password', name: 'Password', component: Password, meta: { title: '修改密碼', }, }, ], }, { path: '/setUp', name: 'SetUp', meta: { title: '系統(tǒng)設(shè)置', icon: '<span class="iconfont icon-celveguanli"/>', }, children: [ { path: '/setUp/avatar', name: 'setUp', component: Avatar, meta: { title: '暫無', }, }, { path: '/setUp/avatar', name: 'setUp', component: Avatar, meta: { title: '暫無', }, }, ], }, ], }, { path: '/login', name: 'Login', component: Login, }, ]; export default routes;
遞歸實(shí)現(xiàn)導(dǎo)航欄渲染
- 對于導(dǎo)航欄渲染難點(diǎn)在于不知道有多少層級的導(dǎo)航,可能一級也可能兩級或者更多
- 為了方便采用兩個(gè)組件父組件aside.vue與子組件subAside.vue渲染導(dǎo)航
- 這時(shí)候就需要采用遞歸的方式
- 首先判斷哪些數(shù)據(jù)需要渲染,需要的拿出來
- 判斷是否有子節(jié)點(diǎn)需要渲染
- 有子節(jié)點(diǎn),遞歸調(diào)用子組件本身
- 沒有子節(jié)點(diǎn),返回導(dǎo)航項(xiàng)進(jìn)行渲染
父組件aside.vue
<template> <el-radio-group v-model="isCollapse" style="margin-bottom: 20px"> <el-radio-button :label="false">expand</el-radio-button> <el-radio-button :label="true">collapse</el-radio-button> </el-radio-group> <el-menu default-active="2" class="el-menu-vertical-demo" :collapse="isCollapse" select="handleSelect" router unique-opened > <!-- 將渲染導(dǎo)航每一項(xiàng)傳給子組件渲染,item代表要渲染每一項(xiàng) --> <SubAside :isCollapse="isCollapse" v-for="(item,index) in navs" :key="item.path" :menu="item" :index="item.path" /> </el-menu> </template> <script lang="ts" setup> import { ref } from 'vue'; import router from '../router/module'; const navs =router.filter((item) => item.meta?.permission)[0].children // 過濾拿到數(shù)據(jù) console.log(navs); const isCollapse = ref(true); // 是否收起,默認(rèn)不收起 </script> <style lang="scss" scoped></style>
父組件處理后的用于渲染的數(shù)據(jù)
[ { component: () => import('/src/views/Home.vue') meta: {title: '首頁', icon: '<span class="iconfont icon-shouye"/>', inSide: true} name: "Home" path: "/home" }, { component: () => import('/src/views/About.vue') meta: {title: '個(gè)人中心', icon: '<span class="iconfont icon-yonghuzhongxin1"/>'} name: "User" path: "/user" chilren:[ { children: [{…}] component: () => import('/src/views/Users/Avatar.vue?t=1655544364909') meta: {title: '修改頭像'} name: "Avatar" path: "/user/avatar" }, { component: () => import('/src/views/Users/Password.vue') meta: {title: '修改密碼'} name: "Password" path: "/user/password" } ] }, { meta: {title: '系統(tǒng)設(shè)置', icon: '<span class="iconfont icon-celveguanli"/>'} name: "SetUp" path: "/setUp" chilren:[ { component: () => import('/src/views/Users/Avatar.vue?t=1655544364909') meta: {title: '暫無'} name: "setUp" path: "/setUp/avatar" }, { component: () => import('/src/views/Users/Avatar.vue?t=1655544364909') meta: {title: '暫無'} name: "setUp" path: "/setUp/avatar" } ] } ]
子組件subAside.vue
<template> <!-- 有子節(jié)點(diǎn)渲染這個(gè) --> <el-sub-menu :index="menu.path" v-if="menu?.children"> <template #title> <el-icon v-html="menu?.meta.icon"></el-icon> <span>{{menu?.meta.title}}</span> </template> <!-- 遞歸調(diào)用本身,該組件在index.ts中全局注冊了 --> <SubAside v-for="item in menu.children" :menu="item" :isCollapse="isCollapse"/> </el-sub-menu> <!-- 沒有子節(jié)點(diǎn)渲染這個(gè) --> <el-menu-item v-else :index="menu?.path"> <el-icon v-html="menu?.meta.icon"></el-icon> <span slot="title">{{menu?.meta.title}}</span> </el-menu-item > </template> <script lang="ts" setup> import { ref } from "vue" // 拿到父組件傳入的值 defineProps({ isCollapse:Boolean, menu:Object }) </script> <style lang="scss" scoped> </style>
配置
版本
"vue": "^3.2.25", "element-plus": "^2.2.6",
main.ts中配置
import { createApp } from 'vue'; import App from './App.vue'; // import 'virtual:windi.css'; import router from './router/index'; /** * 引入elment */ import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import 'element-plus/theme-chalk/dark/css-vars.css' import './styles/dark/css-vars.css' // 引入 Pinia 狀態(tài)管理工具 import pinia from './stores' const app=createApp(App) /** * 全局注冊組件 */ import SubAside from './components/subAside.vue' app.component('SubAside', SubAside) // 注冊Element全局可用 app.use(ElementPlus).use(router).use(pinia).mount('#app');
到此這篇關(guān)于vue3+Element采用遞歸調(diào)用封裝導(dǎo)航欄實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)vue3 Element封裝導(dǎo)航欄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue使用axios實(shí)現(xiàn)文件上傳進(jìn)度的實(shí)時(shí)更新詳解
最近在學(xué)習(xí)axios,然后項(xiàng)目就用到了,所以這篇文章主要給大家介紹了關(guān)于vue中利用axios實(shí)現(xiàn)文件上傳進(jìn)度的實(shí)時(shí)更新的相關(guān)資料,文中先對axios進(jìn)行了簡單的介紹,方法大家理解學(xué)習(xí),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12vue3自定義組件之v-model實(shí)現(xiàn)父子組件雙向綁定
這篇文章主要介紹了vue3自定義組件之v-model實(shí)現(xiàn)父子組件雙向綁定方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08vue-music 使用better-scroll遇到輪播圖不能自動輪播問題
根據(jù)vue-music視頻中slider組建的使用,當(dāng)安裝新版本的better-scroll,輪播組件,不能正常輪播。如何解決這個(gè)問題呢,下面小編給大家?guī)砹藇ue-music 使用better-scroll遇到輪播圖不能自動輪播問題,感興趣的朋友一起看看吧2018-12-12Vue3 使用Vuex和router的注意事項(xiàng)及操作方法
在vue2中 使用的?this.$route?和?this.$router?this.$store的使用在vue3中完全適用,這篇文章主要介紹了Vue3 使用Vuex和router的注意事項(xiàng)及操作方法,需要的朋友可以參考下2022-12-12Vue 2源碼解析HTMLParserOptions.start函數(shù)方法
這篇文章主要為大家介紹了Vue 2源碼解析HTMLParserOptions.start函數(shù)方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08