ToB企服应用市场:ToB评测及商务社交产业平台
标题:
vue3+Element采用递归调用封装导航栏
[打印本页]
作者:
用多少眼泪才能让你相信
时间:
2022-6-25 06:31
标题:
vue3+Element采用递归调用封装导航栏
vue3+Element采用递归调用封装导航栏
效果预览
模拟数据
数据来源有很多,可以是自己写死的,也可以是后端调用得到的,也可以从别的组件中拿到
这里采用从路由中拿
定义数据源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: '', // iconfont图标
inSide: true,
},
},
{
path: '/user',
name: 'User',
component: User,
meta: {
title: '个人中心',
icon: '',
},
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: '系统设置',
icon: '',
},
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;
复制代码
递归实现导航栏渲染
对于导航栏渲染难点在于不知道有多少层级的导航,可能一级也可能两级或者更多
为了方便采用两个组件父组件aside.vue与子组件subAside.vue渲染导航
这时候就需要采用递归的方式
首先判断哪些数据需要渲染,需要的拿出来
判断是否有子节点需要渲染
有子节点,递归调用子组件本身
没有子节点,返回导航项进行渲染
父组件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
>
<SubAside :isCollapse="isCollapse" v-for="(item,index) in navs" :key="item.path" :menu="item" :index="item.path" />
</el-menu>
</template>
复制代码
父组件处理后的用于渲染的数据
[
{
component: () => import('/src/views/Home.vue')
meta: {title: '首页', icon: '', inSide: true}
name: "Home"
path: "/home"
},
{
component: () => import('/src/views/About.vue')
meta: {title: '个人中心', icon: ''}
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: '系统设置', icon: ''}
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>
<el-sub-menu :index="menu.path" v-if="menu?.children">
<template #title>
<el-icon v-html="menu?.meta.icon"></el-icon>
{{menu?.meta.title}}
</template>
<SubAside v-for="item in menu.children" :menu="item" :isCollapse="isCollapse"/>
</el-sub-menu>
<el-menu-item v-else :index="menu?.path">
<el-icon v-html="menu?.meta.icon"></el-icon>
{{menu?.meta.title}}
</el-menu-item >
</template>
复制代码
配置
版本
"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 状态管理工具
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');
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4