index.vue 5.99 KB
<template>
  <div class="side-bar-container" :class="{ 'is-collapse': collapse }">
    <el-scrollbar class="side-left">
      <ul class="new-side-bar">
        <app-logo :is-show-title="false" />
        <li
          v-for="menu in menus"
          :key="menu.id"
          class="new-side-bar-item"
          :class="{ active: menu.id === selectMenuId }"
          @click="selectItem(menu)"
        >
          <i class="item-icon ht-fa-icon" :class="menu.icon"></i>
          {{ menu.name }}
        </li>
      </ul>
    </el-scrollbar>
    <el-scrollbar v-show="!collapse" class="side-right">
      <ul>
        <li class="new-slide-bar-title">{{ appInfo.name }}</li>
        <el-menu
          text-color="#333"
          active-text-color="#fff"
          :default-active="activeMenuIndex"
          :unique-opened="uniqueOpened"
          mode="vertical"
          @select="menuSelect"
        >
          <template v-for="menu in selectMenu">
            <sidebar-item :key="menu.id" :item="menu" :level="1"></sidebar-item>
          </template>
        </el-menu>
      </ul>
    </el-scrollbar>
  </div>
</template>
<script>
  import variables from '@/styles/variables.scss'
  import { mapGetters } from 'vuex'
  import { defaultOopeneds, uniqueOpened } from '@/config'
  import setMenuMark from '@/mixins/setMenuMark'
  import AppLogo from '../logo/index'
  import SidebarItem from './SidebarItem.vue'
  import getValue from 'lodash/get'
  export default {
    name: 'Index',
    components: {
      SidebarItem,
      AppLogo,
    },
    mixins: [setMenuMark],
    data() {
      return {
        uniqueOpened,
        perList: [],
        defaultPerMun: ['security', 'information', 'setting'],
        defFirMun: ['//appCenter', '/appCenter', '//personal', '/personal'],
        selectMenu: [],
        selectMenuId: '',
      }
    },
    computed: {
      ...mapGetters({
        appInfo: 'app/appInfo',
        collapse: 'settings/collapse',
        style: 'app/style',
        themeColor: 'app/themeColor',
        menus: 'app/menus',
        tileMenus: 'app/tileMenus',
        activeMenu: 'app/activeMenu',
      }),
      defaultOpens() {
        if (this.collapse) {
        }
        return defaultOopeneds
      },
      activeMenuIndex() {
        return this.activeMenu?.id
      },
      variables() {
        return variables
      },
    },
    watch: {
      activeMenu: {
        handler(val) {
          if (val) {
            this.initSelectItem()
          }
        },
        immediate: true,
      },
    },
    methods: {
      isActive() {},
      initSelectItem() {
        const item = this.menus.find((item) => {
          return this.findSelectItem(item)
        })
        if (item) {
          this.selectMenuId = item.id
          this.selectItem(item)
        }
      },
      findSelectItem(menus) {
        if (getValue(menus, 'id', null) === this.activeMenu.id) {
          return true
        }
        if (Array.isArray(menus)) {
          return menus.some((item) => {
            return this.findSelectItem(item)
          })
        } else if (menus.children) {
          return this.findSelectItem(menus.children)
        }
        return this.findSelectItem(menus)
      },

      selectItem(menu) {
        if (menu.menuType === 'page') {
          // 一级是页面则直接处理页面逻辑
          this.menuSelect(menu.id)
        }
        this.selectMenu = menu.children
      },
      menuSelect(index) {
        this.$store.dispatch('app/addVisitedMenus', index)
      },
    },
  }
</script>
<style lang="scss" scoped>
  @mixin dot-border-color {
    border-color: var(--themeColor);
  }
  $side-bar-color: rgb(33, 59, 106);
  $side-bar-bg-color: #f2f2f2;
  .side-bar-container {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: $base-z-index;
    width: $base-left-menu-width;
    height: 100vh;
    overflow: hidden;
    background-color: $side-bar-bg-color;
    border-right: 1px solid $side-bar-bg-color;
    transition: width $base-transition-time;
    color: $side-bar-color;
    display: flex;
    .side-left {
      width: $base-left-menu-width-min;
    }
    .side-right {
      width: $base-right-content-width-min;
      background-color: #fff;
      transition: width $base-transition-time;
      position: relative;
      &:after {
        position: absolute;
        content: '';
        display: inline-block;
        bottom: 16px;
        left: 16px;
        right: 16px;
        height: 265px;
        background: url('~@/assets/index_images/side_bg.png') no-repeat
          center/100%;
      }
    }
    &.is-collapse {
      width: $base-left-menu-width-min;
    }
  }

  @mixin hover {
    background-color: var(--themeColor) !important;
    color: #fff !important;
  }
  .new-side-bar {
    display: flex;
    width: $base-left-menu-width-min;
    align-items: center;
    flex-flow: column;
    gap: 4px;
    flex-shrink: 0;
    .new-side-bar-item {
      width: calc(100% - 16px);
      height: 58px;
      display: flex;
      flex-flow: column;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      &.active,
      &:hover {
        @include hover;
      }
    }
    .item-icon {
      width: 24px;
      height: 24px;
      display: inline-block;
      object-fit: contain;
      margin-bottom: 6px;
      font-size: 26px;
      margin-right: inherit;
    }
  }

  .new-slide-bar-title {
    text-align: center;
    line-height: 62px;
    font-size: 22px;
    font-family: 楷体, sans-serif;
  }
  ::v-deep {
    .logo-container-vertical {
      line-height: inherit;
      width: 100%;
      padding: 0;
      height: 58px;
      display: flex;
      align-items: center;
      justify-content: center;
      .logoImg {
        width: 36px;
        height: 36px;
      }
    }
    .el-menu {
      background-color: transparent;
      padding: 0 4px;
      border: none;
    }
    .el-menu-item {
      &:hover,
      &.is-active {
        @include hover;
      }
    }
    .el-submenu__icon-arrow {
      font-size: 20px;
      color: $side-bar-color;
    }
  }
</style>