再是 layout 页面
<template> <div class="app-container"> <sidebar /> <div class="container"> <navtop /> <div class="main"> <!-- 当路由 meta: {Full:false }为fasle 不展示二级路由 不让展示--> <menubar v-show="!menubarFull" /> <!-- 展示主页面 --> <router-view class="main-content"/> </div> </div> </div> </template> <script> computed: { menubarFull() { // 判断二级是不是需要隐藏不渲染 return this.$store.state.menubar.meta.full }, }, watch: {}, mounted() { const routes = this.$router.options.routes // 所有路由 const currentRouter = this.$route.path // 当前活跃的路由 const item = routes.find(x => x.path !=='/' && currentRouter.indexOf(x.path) > -1) if (item) { this.$store.commit('CHANGEMENU', item) } this.$store.dispatch('listGeologyTree') // 省市区 this.$store.dispatch('listRoleName') // 角色展示 <script> }, + 侧边栏 数据信息从 路由里面获取 this.$router.options.routes + defaultRouter 默认的当前一级路由 this.$route.path + <el-menu.> router 路由形式菜单 + routers 为所有路由信息 this.$router.options.routes + <el-menu-item.> index 为待选中路由的标识 + :route="{path: item.path + '/' + item.children[0].path}" 路由形式跳转 + 点击一级 @click.native="select(item)" 把二级存到 vuex中 <template> <div class="sidebar"> <div class="logo"> <img src="@/assets/logo.png" alt=""> <span>营销云</span> </div> <el-menu :default-active="defaultRouter" router class="el-menu-vertical" background-color="#000" text-color="#999" active-text-color="#fff"> <template v-for="(item,index) in routers" > <!-- 遍历循环一级菜单 --> <el-menu-item v-if="!item.hide" @click.native="select(item)" :key="item+index" :index="item.path + '/' + item.children[0].path" :route="{path: item.path + '/' + item.children[0].path}"> <i class="el-icon-menu"></i> <span slot="title">{{item.meta.title}}</span> </el-menu-item> </template> </el-menu> </div> </template> <script> // 获取路由 从路由里面获取路由信息 循环遍历路由 export default { data() { return { defaultRouter: this.$route.path } }, computed: { routers(){ return this.$router.options.routes } }, mounted() {}, methods: { select(item) { this.$store.commit('CHANGEMENU', item) } } } </script> <style lang="scss" scoped> .sidebar{ height: 100%; overflow: auto; width: 120px; background-color: #000; color: #999; float: left; .logo{ padding: 20px; img{ width: 50px; height: 50px; display: block; margin: 0 auto; } span{ font-size: 12px; display: block; text-align: center; margin-top: 10px; color: #999; } } .el-menu-vertical{ border-right: none; .el-menu-item{ >i{ font-size: 14px; } } } } </style> vuex import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { menubar: {meta: {}} // 二级菜单 }, mutations: { CHANGEMENU(state, value) { state.menubar = value } }, actions: { }, modules: { } }) 二级路由 menubar ` defaultRouter 默认的当前二级路由 this.$route.path ` menubar.children 从vuex 获取 为 [] ` :index="menubar.path + '/' + item.path" 为 要点击的标记点 ` :route="{path: menubar.path + '/' + item.path }" 要跳转的路由 ` 点击 1级路由的时候 2级路由会默认一个 home/indexone 默认路由下第一个 ` 二级路由在切换的时候 home/indextwo `路由代码 import Layout from '@/views/layout/index' export const publish = [{ path: '/publish', name: 'publish', meta: { title: '商机发布', icon: 'nested' }, component: Layout, children: [ { path: 'siteInfo', component: () => import('../page/siteInfo'), meta: { title: '站点信息配置' }, }, { path: 'platformBinding', component: () => import('../page/platformBinding'), meta: { title: '平台绑定' }, }, ] }] 二级路由 menubar 二级路由点击切换的时候 需要监听当前活跃路由 为高亮点 computed: { router() { return this.$route.path } }, watch: { router(val) { // 监听当前路由的path this.$refs.myMenu.activeIndex = val } }, <template> <div class="meunbar"> <el-menu :default-active="defaultRouter" ref="myMenu" router class="el-menu-vertical"> <template v-for="(item, index) in menubar.children"> <el-menu-item :key="index" :index="menubar.path + '/' + item.path" :route="{path: menubar.path + '/' + item.path }"> <i class="el-icon-menu"></i> <span slot="title">{{item.meta.title}}</span> </el-menu-item> </template> </el-menu> </div> </template> <script> export default { data() { return { defaultRouter: this.$route.path } }, computed: { menubar() { return this.$store.state.menubar }, router() { return this.$route.path } }, watch: { router(val) { // 监听当前路由的path this.$refs.myMenu.activeIndex = val } }, mounted() { }, methods: {} } </script> <style lang="scss" scoped> .meunbar{ float: left; width: 120px; height: 100%; padding: 20px 0; background-color: #f9f9f9; .el-menu{ background-color: transparent; border-right: none; .el-menu-item{ height: 44px; line-height: 44px; } } } </style>侧边栏
index 标识通过 ``getPath(item) 来解决
<template> <div class="sidebar"> <div class="logo"> <img src="@/assets/logo.png" alt=""> <span>营销云</span> </div> <el-scrollbar> <el-menu :default-active="defaultRouter" router class="el-menu-vertical" background-color="#000" text-color="#999" active-text-color="#fff"> <template v-for="(item,index) in routers" > <!-- 遍历循环一级菜单 --> <el-menu-item v-if="!item.hide" @click.native="select(item)" :key="item+index" :index="getPath(item)"> <svg-icon v-if="item.meta && item.meta.icon" :icon-class="item.meta.icon" /> <span v-if="item.meta && item.meta.title" slot="title">{{item.meta.title}}</span> </el-menu-item> </template> </el-menu> </el-scrollbar> </div> </template> <script> // 获取路由 从路由里面获取路由信息 循环遍历路由 export default { data() { return { defaultRouter: this.$route.path } }, computed: { routers(){ return this.$router.options.routes } }, mounted() {}, methods: { getPath(item) { if (item.children[0].children) { const subMenu = item.children[0].children.find(x => !x.hide) return item.path + '/' + item.children[0].path + '/' + subMenu.path } else { return item.path + '/' + item.children[0].path } }, select(item) { this.$store.commit('CHANGEMENU', item) } } } </script> <style lang="scss" scoped> .sidebar{ height: 100%; overflow: auto; width: 120px; background-color: #000; color: #999; float: left; .logo{ padding: 20px; height: 116px; img{ width: 50px; height: 50px; display: block; margin: 0 auto; } span{ font-size: 12px; display: block; text-align: center; margin-top: 10px; color: #999; } } .el-scrollbar{ height: calc(100% - 116px); ::v-deep .el-scrollbar__wrap{ overflow-x: hidden; } } .el-menu-vertical{ border-right: none; .el-menu-item{ .svg-icon{ margin-right: 8px; } >i{ font-size: 14px; } } } } </style>二级侧边栏 3级侧边栏 解决
!item.hide 通过hide 判断时候不渲染
hasOneChild 判断1级路由下面是否有children
getPath 获取index 标识
<template> <div class="meunbar"> <el-menu :default-active="defaultRouter" ref="myMenu" router class="el-menu-vertical"> <!-- {{defaultRouter}} --> <template v-for="(item, index) in menubar.children"> <template v-if="!item.hide"> <el-menu-item :key="index" v-if="hasOneChild(item)" :index="getPath(item)" > <span slot="title">{{$t(item.meta.title)}}</span> </el-menu-item> <el-submenu :key="index" v-else> <template slot="title"> <span>{{$t(item.meta.title)}}</span> </template> <template v-for="(sub, i) in item.children"> <el-menu-item v-if="!sub.hide" :key="i" :index="getPath(item, sub)">{{$t(sub.meta.title)}}</el-menu-item> </template> </el-submenu> </template> </template> </el-menu> </div> </template> <script> export default { data() { return { defaultRouter: this.$route.path } }, computed: { menubar() { return this.$store.state.menubar }, router() { return this.$route.path } }, watch: { router(val) { // 监听当前路由的path this.$refs.myMenu.activeIndex = val } }, mounted() { }, methods: { getPath(item, sub) { if (this.hasOneChild(item)) { if (item.children) { const subMenu = item.children.find(x => !x.hide) return this.menubar.path + '/' + item.path + '/' + subMenu.path } else { return this.menubar.path + '/' + item.path } } else { return this.menubar.path + '/' + item.path + '/' + sub.path } }, hasOneChild(item) { if (!item.children) { return true } else { const list = item.children.filter(x => !x.hide) if (list.length > 1) { return false } else { return true } } } } } </script> <style lang="scss" scoped> .meunbar{ float: left; width: 120px; height: 100%; padding: 20px 0; background-color: #f9f9f9; .el-menu{ background-color: transparent; border-right: none; .el-menu-item{ height: 44px; line-height: 44px; } } } </style>