Menu.vue 4.27 KB
Newer Older
wanli's avatar
wanli committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
<template>
  <div class="menu" :class="{collapse: menuData.collapse}">
    <div class="logo">
      <div><img src="/logo.png"></div>
      <h1 :class="{hidden: menuData.collapse}">eva</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: {
    // 处理菜单选中
    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)
    },
    // 获取菜单配置
    __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>
89
@import "@/styles/variables.scss";
wanli's avatar
wanli committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
.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">
128
@import "@/styles/variables.scss";
wanli's avatar
wanli committed
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
// 菜单样式
.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>