美文网首页
vue-element-admin 切换顶部导航栏解决方案

vue-element-admin 切换顶部导航栏解决方案

作者: 李小白呀 | 来源:发表于2023-10-14 15:58 被阅读0次

背景

基于vue-element-admin开发,需要控制切换导航菜单

最终效果

不改变导航栏与路由绑定的效果,自由切换侧边栏和顶部导航栏。


image.png

步骤

1.@/styles/sidebar.scss 修改.hideSidebar 的样式

  .hideSidebar {
    .sidebar-container {
      width: 0 !important;  //默认54px,收起时会展示图标,因此我们设为0
    }

    .main-container {
      margin-left: 0;  //默认54px,收起时会留出 54px 的空白,因此我们设为0
    }

    .submenu-title-noDropdown {
      padding: 0 !important;
      position: relative;

      .el-tooltip {
        padding: 0 !important;

        .svg-icon {
          margin-left: 20px;
        }
      }
    }
/*    注释掉.hideSidebar的子样式.el-submenu,避免submenu样式失灵,原因很简单,就是这段代码会导致标题之间距离从原本的20px变成0*/
 /*   .el-submenu {
      overflow: hidden;

      &>.el-submenu__title {
        padding: 0 !important;

        .svg-icon {
          margin-left: 20px;
        }

        .el-submenu__icon-arrow {
          display: none;
        }
      }
    }*/
    .el-menu--collapse {
      .el-submenu {
        &>.el-submenu__title {
          &>span {
            height: 0;
            width: 0;
            overflow: hidden;
            visibility: hidden;
            display: inline-block;
          }
        }
      }
    }
  }

2.

复制一份@/views/layout/Sidebar 组件,粘贴到相同路径下,更改组件名为HeadNavbar,并判断是左侧菜单还是顶部菜单


image.png
image.png

在index.js中声明组件


image.png
@/views/layout/HeadNavbar/index.vue 将template修改如下:
<template>
  <div :class="{'has-logo':showLogo}">
    <!-- 判断是否需要左侧菜单logo -->
    <logo
      v-if="showLogo&&this.sitePropery=='left'"
      :collapse="isCollapse"
    />
    <div>
      <el-scrollbar wrap-class="scrollbar-wrapper">
        <!-- 判断是否需要左侧菜单标题 -->
        <div
          v-if="this.sitePropery=='left'"
          class="h5"
        >{{title}}</div>
        <el-menu
          :default-active="activeMenu"
          :background-color="variables.menuBg"
          :text-color="variables.menuText"
          :unique-opened="true"
          :active-text-color="variables.menuActiveText"
          :collapse-transition="false"
          @select="handleSelect"
          mode="horizontal"
        >
          <sidebar-item
            v-for="route in permission_routes"
            :key="route.path"
            :item="route"
            :base-path="route.path"
          />
        </el-menu>
      </el-scrollbar>
      <div class="panel">
        <span style="margin-right: 10px;">导航面板</span>
        <el-link
          :underline="false"
          type="info"
          v-for="item in this.pathList"
          :key="item.path"
          @click="handleOpen(item.path)"
          style="margin:0 10px;"
        >{{item.name}}</el-link>
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/styles/qlm-uivariables.scss'
import { qlm_setValue } from '@/utils/qlm_store'

export default {
  components: { SidebarItem, Logo },
  data() {
    return {
      title: this.$t('system.title'),
      pathList: [],
      sitePropery: this.$store.getters.sitePropery.menuMode
      // sitePropery: 'left'
    }
  },
  created() {

    //因为是新打开窗口,需要重新初始化数据
    this.$store.dispatch("qlm_user/getUserInfo").then(
      ret => {
        let namearray = this.$store.getters.rolenames;
        let name = ""

        if (namearray != null && namearray.length > 0) {
          name = namearray[0]
        }
      }
    )
  },
  mounted() {

  },
  computed: {
    ...mapGetters([
      'permission_routes',
      'sidebar'
    ]),
    activeMenu() {
      const route = this.$route
      const { meta, path } = route
      // if set path, the sidebar will highlight the path you set
      if (meta.activeMenu) {
        return meta.activeMenu
      }
      return path
    },
    showLogo() {
      return this.$store.state.qlm_settings.sidebarLogo
    },
    variables() {
      return variables
    },
    isCollapse() {
      return !this.sidebar.opened
    },
  },
  methods: {
    handleSelect(key, keyPath) {
      localStorage.setItem('keyPath', key)
      qlm_setValue("QLMPath", key)
    },
    handleOpen(path, keyPath) {
      // this.$message.success(path)
      this.$router.push(path)
    },
  },
}
</script>

<style lang="scss" scoped>
>>> .el-scrollbar__view {
  display: flex;
  // background-color: #182b5c;
  // height: 112px;
  .h5 {
    height: 56px;
    padding: 0 20px;
    line-height: 56px;
    color: #fff;
    font-size: 20px;
    font-weight: 600;
    text-align: center;
    background-color: #2386ee;
  }
  .el-menu {
    flex: 1;
  }
}
.panel {
  background-color: #182b5c;
  min-height: 56px;
  line-height: 56px;
  padding: 0 25px;
  color: #bfcbd9;
}

>>> .el-scrollbar__wrap {
  overflow: hidden;
  margin-bottom: 0px !important;
}
.el-menu.el-menu--horizontal {
  // border-bottom: 0;
  border-bottom: solid 1px #111;
}
.icon-arrow {
  >>> .el-submenu__icon-arrow {
    position: static;
  }
}
</style>

@/views/layout/HeadNavbar/SidebarItem.vue 将template修改如下:

<template>
  <!-- style设置为inline-block,避免标题垂直布局-->
  <div
    v-if="!item.hidden"
    style="display:inline-block;"
    :class="{'icon-arrow':this.sitePropery=='top'}"
  >
    <template
      v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"
    >
      <app-link
        v-if="onlyOneChild.meta"
        :to="resolvePath(onlyOneChild.path)"
      >
        <el-menu-item
          :index="resolvePath(onlyOneChild.path)"
          :class="{'submenu-title-noDropdown':!isNest}"
        >
          <item
            :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)"
            :title="generateTitle(onlyOneChild.meta.title)"
          />
        </el-menu-item>
      </app-link>
    </template>

    <el-submenu
      v-else
      ref="subMenu"
      :index="resolvePath(item.path)"
      popper-append-to-body
    >
      <template slot="title">
        <item
          v-if="item.meta"
          :icon="item.meta.icon"
          :title="generateTitle(item.meta.title)"
        >
        </item>
      </template>
      <sidebar-item
        v-for="child in item.children"
        :key="child.path"
        :is-nest="true"
        :item="child"
        :base-path="resolvePath(child.path)"
        class="nest-menu"
      />
    </el-submenu>
  </div>
</template>

<style lang="scss">
.nest-menu {
  display: block !important;
}
.el-submenu {
  padding-right: 20px;
}
// .el-submenu__title {
//   margin-right: 20px;
// }

.icon-arrow {
  >>> .el-submenu__icon-arrow {
    position: static;
  }
}
</style>

3.完成以上步骤以后顶部导航栏的组件就改造好了,只需要在index.vue 下引入就可以使用。

<template>
  <div
    :class="classObj"
    class="app-wrapper"
  >
    <div
      v-if="device==='mobile'&&sidebar.opened"
      class="drawer-bg"
      @click="handleClickOutside"
    />
    <!-- 判断是否左侧菜单 -->
    <sidebar
      v-if="this.sitePropery=='left'"
      class="sidebar-container"
    />
    <!-- 判断是否需要左侧菜单宽度 -->
    <div
      :class="{hasTagsView:needTagsView,'main-container':this.sitePropery=='left'}"
    >
      <div :class="{'fixed-header':fixedHeader}">
        <navbar />
        <!-- 判断是否顶部菜单 -->
        <head-navbar v-if="this.sitePropery=='top'" />
        <tags-view v-if="needTagsView" />
      </div>
      <app-main />
      <right-panel v-if="showSettings">
        <settings />
      </right-panel>
    </div>
  </div>
</template>

<script>
import RightPanel from '@/components/RightPanel'
import { AppMain, Navbar, Settings, Sidebar, TagsView, HeadNavbar } from './components'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'

export default {
  name: 'Layout',
  components: {
    AppMain,
    Navbar,
    RightPanel,
    Settings,
    Sidebar,
    TagsView,
    HeadNavbar
  },

参考文章:vue-element-admin 生成顶部导航栏解决方案

相关文章

网友评论

      本文标题:vue-element-admin 切换顶部导航栏解决方案

      本文链接:https://www.haomeiwen.com/subject/isezbdtx.html