| ¶Ô±ÈÐÂÎļþ | 
 |  |  | 
 |  |  | <template> | 
 |  |  |   <div class="menu" :class="{collapse: menuData.collapse}"> | 
 |  |  |     <div class="logo"> | 
 |  |  |       <div><img src="@/assets/logo.png"></div> | 
 |  |  |       <h1 :class="{hidden: menuData.collapse}">è±ç±³è·³è·³å®ç½åå°ç®¡ç</h1> | 
 |  |  |     </div> | 
 |  |  |     <scrollbar> | 
 |  |  |       <el-menu | 
 |  |  |         ref="menu" | 
 |  |  |         :default-active="activeIndex" | 
 |  |  |         text-color="#fff" | 
 |  |  |         active-text-color="#fff" | 
 |  |  |         :collapse="menuData.collapse" | 
 |  |  |         :default-openeds="defaultOpeneds" | 
 |  |  |         :collapse-transition="false" | 
 |  |  |         @select="handleSelect" | 
 |  |  |       > | 
 |  |  |         <MenuItems v-for="menu in menuData.list" :key="menu.index" :menu="menu" :is-root-menu="true"/> | 
 |  |  |       </el-menu> | 
 |  |  |     </scrollbar> | 
 |  |  |   </div> | 
 |  |  | </template> | 
 |  |  |  | 
 |  |  | <script> | 
 |  |  | import { mapState } from 'vuex' | 
 |  |  | import MenuItems from './MenuItems' | 
 |  |  | import Scrollbar from './Scrollbar' | 
 |  |  | export default { | 
 |  |  |   name: 'Menu', | 
 |  |  |   components: { Scrollbar, MenuItems }, | 
 |  |  |   computed: { | 
 |  |  |     ...mapState(['menuData']), | 
 |  |  |     // éä¸çèåindex | 
 |  |  |     activeIndex () { | 
 |  |  |       let path = this.$route.path | 
 |  |  |       if (path.endsWith('/')) { | 
 |  |  |         path = path.substring(0, path.length - 1) | 
 |  |  |       } | 
 |  |  |       const menuConfig = this.__getMenuConfig(path, 'url', this.menuData.list) | 
 |  |  |       if (menuConfig == null) { | 
 |  |  |         return null | 
 |  |  |       } | 
 |  |  |       return menuConfig.index | 
 |  |  |     }, | 
 |  |  |     // é»è®¤å±å¼çèåindex | 
 |  |  |     defaultOpeneds () { | 
 |  |  |       return this.menuData.list.map(menu => menu.index) | 
 |  |  |     } | 
 |  |  |   }, | 
 |  |  |   methods: { | 
 |  |  |     /** | 
 |  |  |      * å¤çèåéä¸ | 
 |  |  |      * | 
 |  |  |      * @param menuIndex éä¸çèåç´¢å¼ | 
 |  |  |      */ | 
 |  |  |     handleSelect (menuIndex) { | 
 |  |  |       const menuConfig = this.__getMenuConfig(menuIndex, 'index', this.menuData.list) | 
 |  |  |       // æ¾ä¸å°é¡µé¢ | 
 |  |  |       try { | 
 |  |  |         require('@/views' + menuConfig.url) | 
 |  |  |       } catch (e) { | 
 |  |  |         this.$tip.error('æªæ¾å°é¡µé¢æä»¶@/views' + menuConfig.url + '.vueï¼è¯·æ£æ¥èåè·¯å¾æ¯å¦æ£ç¡®') | 
 |  |  |       } | 
 |  |  |       // ç¹å»å½åèåä¸åå¤ç | 
 |  |  |       if (menuConfig.url === this.$route.path) { | 
 |  |  |         return | 
 |  |  |       } | 
 |  |  |       if (menuConfig.url == null || menuConfig.url.trim().length === 0) { | 
 |  |  |         return | 
 |  |  |       } | 
 |  |  |       this.$router.push(menuConfig.url) | 
 |  |  |     }, | 
 |  |  |     /** | 
 |  |  |      * è·åèåé
ç½® | 
 |  |  |      * | 
 |  |  |      * @param value å¯ä¸æ è¯å¼ | 
 |  |  |      * @param key å¯ä¸æ è¯key | 
 |  |  |      * @param menus æ¥æ¾èåèå´ | 
 |  |  |      * @returns {null|*|null} | 
 |  |  |      * @private | 
 |  |  |      */ | 
 |  |  |     __getMenuConfig (value, key, menus) { | 
 |  |  |       for (const menu of menus) { | 
 |  |  |         if (menu[key] === value) { | 
 |  |  |           return menu | 
 |  |  |         } | 
 |  |  |         if (menu.children != null && menu.children.length > 0) { | 
 |  |  |           const menuConfig = this.__getMenuConfig(value, key, menu.children) | 
 |  |  |           if (menuConfig != null) { | 
 |  |  |             return menuConfig | 
 |  |  |           } | 
 |  |  |         } | 
 |  |  |       } | 
 |  |  |       return null | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  | } | 
 |  |  | </script> | 
 |  |  |  | 
 |  |  | <style lang="scss" scoped> | 
 |  |  | @import "@/assets/style/variables.scss"; | 
 |  |  | .menu { | 
 |  |  |   height: 100%; | 
 |  |  |   display: flex; | 
 |  |  |   flex-direction: column; | 
 |  |  |   // LOGO | 
 |  |  |   .logo { | 
 |  |  |     height: 60px; | 
 |  |  |     flex-shrink: 0; | 
 |  |  |     line-height: 60px; | 
 |  |  |     overflow: hidden; | 
 |  |  |     display: flex; | 
 |  |  |     background: $primary-color - 20; | 
 |  |  |     padding: 0 16px; | 
 |  |  |     & > div { | 
 |  |  |       width: 32px; | 
 |  |  |       flex-shrink: 0; | 
 |  |  |       margin-right: 12px; | 
 |  |  |       img { | 
 |  |  |         width: 100%; | 
 |  |  |         flex-shrink: 0; | 
 |  |  |         vertical-align: middle; | 
 |  |  |         position: relative; | 
 |  |  |         top: -2px; | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |     h1 { | 
 |  |  |       font-size: 16px; | 
 |  |  |       font-weight: 500; | 
 |  |  |       transition: opacity ease .3s; | 
 |  |  |       overflow: hidden; | 
 |  |  |       &.hidden { | 
 |  |  |         opacity: 0; | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  | } | 
 |  |  | </style> | 
 |  |  | <style lang="scss"> | 
 |  |  | @import "@/assets/style/variables.scss"; | 
 |  |  | // èåæ ·å¼ | 
 |  |  | .el-menu { | 
 |  |  |   border-right: 0 !important; | 
 |  |  |   user-select: none; | 
 |  |  |   background: $primary-color !important; | 
 |  |  |   .el-menu-item { | 
 |  |  |     background: $primary-color; | 
 |  |  |     // éä¸ç¶æ | 
 |  |  |     &.is-active { | 
 |  |  |       background: $primary-color - 40 !important; | 
 |  |  |     } | 
 |  |  |     // æ¬æµ® | 
 |  |  |     &:hover { | 
 |  |  |       background-color: $primary-color - 12; | 
 |  |  |     } | 
 |  |  |     &:focus { | 
 |  |  |       background: $primary-color; | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |   // åèå | 
 |  |  |   .el-submenu { | 
 |  |  |     .el-submenu__title{ | 
 |  |  |       background-color: $primary-color; | 
 |  |  |     } | 
 |  |  |     &.is-active { | 
 |  |  |       .el-submenu__title{ | 
 |  |  |         background-color: $primary-color - 20; | 
 |  |  |       } | 
 |  |  |       .el-menu .el-menu-item{ | 
 |  |  |         background-color: $primary-color - 20; | 
 |  |  |         // æ¬æµ® | 
 |  |  |         &:hover { | 
 |  |  |           background-color: $primary-color - 30; | 
 |  |  |         } | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |     // èåä¸ä¸ç®å¤´ | 
 |  |  |     .el-submenu__title i { | 
 |  |  |       color: #f7f7f7; | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |   // èå徿  | 
 |  |  |   i:not(.el-submenu__icon-arrow) { | 
 |  |  |     color: #f7f7f7 !important; | 
 |  |  |     position: relative; | 
 |  |  |     top: -1px; | 
 |  |  |     // èªå®ä¹å¾æ  | 
 |  |  |     &[class^="eva-icon-"] { | 
 |  |  |       width: 24px; | 
 |  |  |       margin-right: 5px; | 
 |  |  |       background-size: 15px; | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  | } | 
 |  |  | </style> |