Newer
Older
smart-metering-front / src / layouts / components / Header / index.vue
Stephanie on 22 Dec 2022 5 KB feat<components>: 修改全局UI
<script lang="ts" setup name="NewHeader">
import Logo from '../Logo/index.vue'
import Tools from '../Tools/index.vue'
import TopMenu from '../TopMenu/topMenu.vue'
import useSettingsStore from '@/store/modules/settings'
import useMenuStore from '@/store/modules/menu'
import headerImage from '@/assets/images/header-image.png'

const settingsStore = useSettingsStore()
const menuStore = useMenuStore()

const { switchTo } = useMenu()

const navRef = ref()

// 顶部模式鼠标滚动
function handlerMouserScroll(event: WheelEvent) {
  navRef.value.scrollBy({
    left: (event.deltaY || event.detail) > 0 ? 50 : -50,
  })
}
</script>

<template>
  <transition name="header">
    <header v-if="settingsStore.mode === 'pc' && (settingsStore.menu.menuMode === 'head' || settingsStore.menu.menuMode === 'top')">
      <div class="header-container">
        <div class="main">
          <logo :show-logo="settingsStore.app.enableLogo" />
          <!-- 混合模式-主导航 -->
          <div v-if="settingsStore.menu.menuMode === 'head'" ref="navRef" class="nav" @wheel.prevent="handlerMouserScroll">
            <template v-for="(item, index) in menuStore.allMenus" :key="index">
              <div v-if="item.children && item.children.length !== 0" class="item-container" :class="{ active: index === menuStore.actived }">
                <div class="item" :class="`${settingsStore.menu.hoverStyle}-item`" @click="switchTo(index)">
                  <el-icon v-if="(settingsStore.menu.showIcon || item.meta.icon)">
                    <svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
                  </el-icon>
                  <span v-if="item.meta.title">{{ item.meta.title }}</span>
                </div>
              </div>
            </template>
          </div>
          <!-- 顶部模式-菜单  -->
          <div v-if="settingsStore.menu.menuMode === 'top'" ref="navRef" class="nav" @wheel.prevent="handlerMouserScroll">
            <top-menu />
          </div>
        </div>
        <tools />
      </div>
      <el-image :src="headerImage" fit="cover" style="position: absolute;width: 100%;height: 100%;z-index: -1;" />
    </header>
  </transition>
</template>

<style lang="scss" scoped>
header {
  position: fixed;
  z-index: 1000;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  // padding: 0 20px;
  height: var(--g-header-height);
  color: var(--g-header-color);
  background-color: var(--g-header-bg);
  background-image: linear-gradient(90deg, #71b5ff 30%, #3d7eff);
  transition: background-color 0.3s, var(--el-transition-color);

  .header-container {
    width: var(--g-header-width);
    height: 100%;
    margin: 0 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .main {
      flex: 1;
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      height: 100%;
    }
  }

  @media screen and (max-width: var(--g-header-width)) {
    .header-container {
      width: 100%;
    }
  }

  :deep(.title) {
    position: relative;
    width: inherit;
    height: inherit;
    padding: inherit;
    background-color: inherit;

    .logo {
      width: 50px;
      height: 50px;
    }

    span {
      font-size: 22px;
      font-weight: 300;
      letter-spacing: 1px;
      font-family: "Microsoft YaHei";
      color: var(--g-header-color);
    }
  }

  .nav {
    flex: 1;
    display: flex;
    width: 0;
    height: 100%;
    margin: 0 30px;
    padding: 0 20px;
    overflow-x: auto;
    mask-image: linear-gradient(to right, transparent, #000 20px, #000 calc(100% - 20px), transparent);

    // firefox隐藏滚动条
    scrollbar-width: none;

    // chrome隐藏滚动条
    &::-webkit-scrollbar {
      display: none;
    }

    .item-container {
      position: relative;
      display: flex;
      width: initial;
      align-items: center;
      padding: 0 10px;

      .item {
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 5px;
        height: auto;
        cursor: pointer;
        color: var(--g-header-menu-color);
        background-color: var(--g-header-bg);
        transition: background-color 0.3s, var(--el-transition-color);
        font-size: 16px;

        &:hover {
          color: var(--g-header-menu-hover-color);
          background-color: var(--g-header-menu-hover-bg);
        }

        .el-icon {
          font-size: 16px;
          vertical-align: middle;
        }

        span {
          text-align: center;
          vertical-align: middle;
          word-break: break-all;

          @include text-overflow(1, false);
        }

        .el-icon + span {
          margin-left: 5px;
        }
      }

      .item + .item {
        margin-left: 5px;
      }

      .round-item {
        padding: 9px 20px 11px;
        border-radius: 50px;
      }

      .square-item {
        height: 100%;
      }

      &.active .item {
        color: var(--g-header-menu-active-color);
        background-color: var(--g-header-menu-active-bg);
      }
    }
  }

  :deep(.tools) {
    padding: 0;

    .buttons .item .el-icon {
      color: var(--g-header-color);
    }

    .user-container {
      font-size: 16px;
      color: var(--g-header-color);
    }
  }
}

// 头部动画
.header-enter-active,
.header-leave-active {
  transition: transform 0.3s;
}

.header-enter-from,
.header-leave-to {
  transform: translateY(calc(var(--g-header-height) * -1));
}
</style>