<!-- @format --> <template> <div class="nav-side" :key="'navSide_' + $route.name"> <div class="nav-sub" v-show="isShow"> <ul> <li v-show="!backTo" ><span class="nav-sub-head ng-scope" translate="COMPANY">{{ title }}</span></li > <li v-show="backTo"> <span class="nav-sub-head h5 ng-scope nav-sub-head-back" style="box-sizing: border-box; cursor: pointer" @click="navigation(backTo)"> <i class="iconfont"></i> <span>返回</span> </span> </li> <li v-for="(menu, index) in menus" :key="index"> <router-link class="nav-sub-item" active-class="nav-sub-current" :to="{ name: menu.name }" append> <span>{{ menu.label }}</span> </router-link> </li> </ul> </div> <div class="content-main"> <router-view /> </div> </div> </template> <script lang="ts"> import { SideMenu, configRegist } from '/nerv-lib/paas/store/modules/config-service'; import { defineComponent } from 'vue'; // import { storeToRefs, mapWritableState } from 'pinia'; import { findIndex } from 'lodash-es'; export default defineComponent({ name: 'SideNavMultilevel', components: {}, setup() { const configReg = configRegist(); return { configReg, }; }, data(): { title: string; menus: Array<any>; isShow: boolean; backTo: string; currName: string; } { return { title: '', menus: [], isShow: true, backTo: '', //是否需要返回按钮 currName: '', //标记自己当前的路由配置取值key }; }, beforeCreate() {}, mounted() { let sideMenu: SideMenu; let currUrl = this.$route.name; let activeUrl = ''; let urlMap: any[] = this.$route.path.split('/'); //订阅路由激活状态。如果有更深层级的side-nav激活,就隐藏当前的菜单 this.configReg.$subscribe((mutation, state) => { console.log('sub'); this.isShow = this.configReg.isLaster(this.currName); }); try { const routeMatched = this.$route.matched.reverse(); console.log(routeMatched); routeMatched.some((el) => { if (el.meta['sideMenus'] && !this.configReg.hasUrl(el.name)) { sideMenu = el.meta['sideMenus']; this.currName = el.name || ''; this.backTo = sideMenu['backTo'] || ''; this.title = sideMenu.title || ''; this.menus = sideMenu.menus; this.isShow = true; this.menus.forEach((item) => { if (item.name === currUrl) { activeUrl = item.name; } }); // let index = -1; // urlMap.some((el, ind) => { // if (el === el.name) { // index = ind; // } // }); let index = findIndex(urlMap, function (o) { return o === el.name; }); this.configReg.setUrl(el.name, index); return true; } }); //如果没有激活的路由,而且是当前side-nav的默认路由,就取第一个跳转 if (!activeUrl && sideMenu.name === currUrl) { activeUrl = this.menus[0]['name']; } } catch (err) { console.log(err); } if (activeUrl) { this.navigation(activeUrl); } else { this.navigation2(this.$route.path); } }, unmounted() { // configReg.activateUrls = configReg.activateUrls.filter((el) => { // return el !== this.currName; this.configReg.removeUrl(this.currName); }, methods: { navigation(url: string) { this.$router.push({ name: url }); }, navigation2(url: string) { this.$router.push({ path: url }); }, }, }); </script> <style lang="less" scoped> .nav-side { display: flex; height: 100%; .nav-sub { float: left; // height: 100%; overflow: auto; width: 149px; background-color: #f7f9fb; .nav-sub-head { padding-left: 16px; padding-right: 16px; display: inline-block; box-sizing: border-box; width: 100%; font-weight: 700; height: 56px; line-height: 56px; } .nav-sub-head-back { .iconfont { color: #00acff !important; display: inline-block; transform: scale(0.7); font-size: 12px; } span { color: #00acff !important; } } .nav-sub-item { color: #212529; display: inline-block; box-sizing: border-box; width: 100%; padding-left: 16px; padding-right: 16px; height: 48px; line-height: 48px; &:hover { background-color: #fff; } } .nav-sub-current { background-color: #fff; color: @layout-nav-hover; } } } .content-main { width: calc(100% - 149px); background-color: #ffffff; } ul, li { list-style: none; padding: 0; } </style>