根据下面步骤写动态路由左菜单,直接套用就可用。后面请求接口直接渲染即可。
效果图:
1、首先,我们先新建一个menu文件
<template>
<div>
<template v-for="(item, index) in menuList" :key="item.path">
<!-- 没有子路由 -->
<template v-if="!item.children">
<el-menu-item :index="item.path" v-if="!item.meta.hidden">
<template #title>
<!-- 图标 -->
<el-icon>
<component :is="item.meta.icon"></component>
</el-icon>
<span>{
{ item.meta.title }}</span>
</template>
</el-menu-item>
</template>
<!-- 有子路由,但只有一个子路由 -->
<template v-if="item.children && item.children.length == 1">
<el-menu-item
v-if="!item.children[0].meta.hidden"
:index="item.children[0].path"
>
<template #title>
<!-- 图标 -->
<el-icon>
<component :is="item.children[0].meta.icon"></component>
</el-icon>
<span>{
{ item.children[0].meta.title }}</span>
</template>
</el-menu-item>
</template>
<!-- 有子路由,并且大于一个 -->
<el-sub-menu
:index="item.path"
v-if="item.children && item.children.length > 1"
>
<template #title>
<!-- 图标 -->
<el-icon>
<component :is="item.meta.icon"></component>
</el-icon>
<span>{
{ item.meta.title }}</span>
</template>
<!-- 路由递归 : 二级路由还有子路由,子路由又还有子路由-->
<Menu :menuList="item.children"></Menu>
</el-sub-menu>
</template>
</div>
</template>
<script lang="ts" setup>
import { reactive, toRefs, ref } from 'vue'
// 获取父组件传递过来的全部路由数组
defineProps(['menuList'])
</script>
<!-- 递归的 -->
<script lang="ts">
export default {
name: 'Menu',
}
</script>
<style lang="scss" scoped></style>
2、新建路由
export const constantRoute = [
{
path: '/login',
component: () => import('@/views/login/index.vue'),
name: 'login',
meta:{
title:'登录',
hidden:true,
icon:'Promotion'
}
},
{
path: '/',
component: () => import('@/layout/index.vue'),
name: 'layout',
meta:{
title:'layout',
hidden:false,
icon:'Avatar'
},
redirect:'/home',
children:[
{
path:'/home',
component:()=>import('@/views/home/index.vue'),
meta:{
title:'首页',
hidden:false,
icon:'HomeFilled'
}
},
{
path:'/home',
component:()=>import('@/views/home/index.vue'),
meta:{
title:'测试',
hidden:false,
icon:'HomeFilled'
}
},
]
},
{
path: '/404',
component: () => import('@/views/404/index.vue'),
name: '404',
meta:{
title:'404',
hidden:true,
icon:'DocumentDelete'
}
},
{
path: '/:pathMatch(.*)*',
redirect: '/404',
name: 'Any',
meta:{
title:'任意路由',
hidden:true,
icon:'DataLine'
}
},
]
3、新建一个仓库store,将导出的路由存在仓库里
import {constantRoute} from '@/router/routes' //引入
let userUserStore = defineStore('User', {
// 仓库
state: ():UserState => {
return {
token:GET_TOKEN()!, //token
menuRoutes:constantRoute, //存储menu菜单(路由)
}
},
// 异步|逻辑
actions: {
},
getters: {
}
})
export default userUserStore
4、在要用到的layout布局页面,引入使用menu文件、引入仓库获取数据
<template>
<div class="layout_container">
<div class="layout_slider">
<Logo />
<el-scrollbar class="scrollbar">
<el-menu background-color="#001529" text-color="#fff">
<!-- 根据路由动态生成菜单 -->
<Menu :menuList='userStore.menuRoutes'></Menu>
</el-menu>
</el-scrollbar>
</div>
<div class="layout_tabber">456</div>
<div class="layout_main">
<p style="height: 100vh">13123213</p>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import Logo from './logo/index.vue'
import Menu from './menu/index.vue'
// 获取仓库数据
import userUserStore from '@/store/modules/user';
let userStore = userUserStore()
</script>
5、注册全局图标,在component 文件下,新建index.ts,关于使用menu、和路由中可以看到
// 引入项目中全部的全局组件
import SvgIcon from './Svgicon/index.vue'
import Pagination from './Pagination/index.vue'
// 全局引入icon图标
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
// 全局对象
const allGloablComponent: any = {
SvgIcon,
Pagination,
}
export default {
// 务必叫做install方法
install(app: any) {
// 注册为全局组件
Object.keys(allGloablComponent).forEach((key) => {
app.component(key, allGloablComponent[key])
});
// icon图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
},
}
6、main.ts引入全局组件
// 引入自定义插件对象:注册整个项目全局组件
import gloalComponent from '@/components'
// 安装自定义插件
app.use(gloalComponent)
上一篇是关于注册 iconfont 注册为全局组件