增加了仿七牛云的双层侧边栏导航

master
toesbieya 6 years ago
parent a6a19976e2
commit 4925fd52af
  1. 3
      vue/src/asset/style/transition.scss
  2. 2
      vue/src/asset/style/variables.scss
  3. 2
      vue/src/component/Icon/index.vue
  4. 35
      vue/src/component/menu/NavMenu/index.vue
  5. 6
      vue/src/component/menu/NavMenu/item.vue
  6. 114
      vue/src/component/menu/NavMenu/style.scss
  7. 45
      vue/src/layout/component/Aside/Logo.vue
  8. 222
      vue/src/layout/component/Aside/OnePart/index.vue
  9. 86
      vue/src/layout/component/Aside/TwoPart/index.vue
  10. 101
      vue/src/layout/component/Aside/TwoPart/root.vue
  11. 103
      vue/src/layout/component/Aside/TwoPart/sub.vue
  12. 228
      vue/src/layout/component/Aside/index.vue
  13. 0
      vue/src/layout/component/Header/Navbar/component/Bell.vue
  14. 0
      vue/src/layout/component/Header/Navbar/component/Hamburger.vue
  15. 8
      vue/src/layout/component/Header/Navbar/component/HeadMenu.vue
  16. 62
      vue/src/layout/component/Header/Navbar/index.vue
  17. 0
      vue/src/layout/component/Header/TagsView/ScrollPanel.vue
  18. 0
      vue/src/layout/component/Header/TagsView/index.vue
  19. 0
      vue/src/layout/component/Header/TagsView/style.scss
  20. 101
      vue/src/layout/component/Header/component/Navbar/style.scss
  21. 4
      vue/src/layout/component/Header/index.vue
  22. 8
      vue/src/layout/util.js

@ -209,19 +209,16 @@ $transition-easing: cubic-bezier(0.215, 0.61, 0.355, 1);
&-enter-to,
&-leave {
transform: perspective(400px) rotate3d(1, 1, 0, 0deg)
}
}
.flip-right {
&-enter {
transform: perspective(400px) rotate3d(0, 1, 0, -180deg)
}
&-leave-to {
transform: perspective(400px) rotate3d(0, 1, 0, 180deg)
}
}

@ -51,7 +51,7 @@ $--font-path: '~element-ui/lib/theme-chalk/fonts';
$menu-icon-text-gap: 10px;
//侧边菜单icon的大小
$aside-icon-size: 14px;
$aside-icon-size: 16px;
//侧边栏菜单的背景色
$aside-menu-background: #304156;
//侧边栏子菜单的背景色

@ -11,6 +11,8 @@ export default {
render(h, context) {
const {data, props: {icon}} = context
if (!icon) return
//svg
if (icon.startsWith(SVG_PREFIX)) {
return (

@ -11,11 +11,31 @@ export default {
mode: {type: String, default: 'vertical'},
collapse: Boolean,
showParentOnCollapse: Boolean,
showIconMaxDepth: {type: Number, default: 1}
showIconMaxDepth: {type: Number, default: 1},
switchTransition: Boolean,
switchTransitionName: {type: String, default: 'sidebar'}
},
render(h, context) {
const {data, props: {mode, menus, collapse, showParentOnCollapse, showIconMaxDepth}} = context
const {
data, children,
props: {
mode, menus, collapse, showParentOnCollapse,
showIconMaxDepth, switchTransition, switchTransitionName
}
} = context
let items = children || menus.map(m => (
<Item
menu={m}
show-parent={showParentOnCollapse}
collapse={collapse}
show-icon-max-depth={showIconMaxDepth}
/>
))
if (switchTransition) {
items = <transition-group name={switchTransitionName}>{items}</transition-group>
}
return (
<el-menu
@ -26,16 +46,11 @@ export default {
collapse-transition={false}
{...data}
>
{menus.map(m => (
<Item
menu={m}
show-parent={showParentOnCollapse}
collapse={collapse}
show-icon-max-depth={showIconMaxDepth}
/>
))}
{items}
</el-menu>
)
}
}
</script>
<style lang="scss" src="./style.scss"></style>

@ -1,7 +1,5 @@
<script type="text/jsx">
const MenuItemContent = {
name: "NavMenuItemContent",
functional: true,
props: {icon: String, title: String, useTitleAsIcon: Boolean},
@ -11,7 +9,7 @@ const MenuItemContent = {
const iconComponent =
useTitleAsIcon
? <em>{title[0]}</em>
? <i class="icon" style="font-style: normal">{title[0]}</i>
: icon
? <v-icon icon={icon}/>
: <span class="icon" style="display: none"/>
@ -116,8 +114,6 @@ function renderMenu(h, {menu, showParent, collapse, showIconMaxDepth, depth = 1}
}
export default {
name: "NavMenuItem",
functional: true,
props: {

@ -1,59 +1,9 @@
@import "~@/asset/style/variables.scss";
//侧边栏
.aside {
display: flex;
flex-direction: column;
width: $aside-width;
background-color: $aside-menu-background;
font-size: 0;
flex-shrink: 0;
height: 100vh;
z-index: 10;
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
transition: all 0.2s ease-in-out;
//折叠状态
&.collapse {
width: $aside-icon-size + 20px * 2;
}
> .sidebar-logo-container {
position: relative;
width: 100%;
height: $nav-height;
line-height: $nav-height;
text-align: center;
.sidebar-logo-link {
height: 100%;
width: 100%;
.sidebar-logo {
width: 32px;
height: 32px;
vertical-align: middle;
margin-right: 12px;
}
.sidebar-title {
display: inline-block;
margin: 0;
color: #ffffff;
font-weight: 600;
line-height: $nav-height;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
}
&.collapse {
.sidebar-logo {
margin-right: 0;
}
}
}
//原始样式使用 '>' 可能导致侧边栏折叠时还会显示右侧箭头图标
//此样式只对垂直状态生效
.el-menu--collapse .el-submenu .el-submenu__title .el-submenu__icon-arrow {
display: none;
}
/*-------侧边栏垂直菜单开始---------*/
@ -107,4 +57,60 @@
border-bottom: 1px solid $aside-sub-menu-background;
}
}
/*-------侧边栏垂直菜单结束---------*/
/*-------顶部水平菜单开始-----------*/
.el-menu--horizontal .el-menu,
.el-menu--horizontal.el-menu {
font-size: 14px;
.icon {
font-size: 14px;
}
//图标和文字的间隔
.icon + .menu-item-content {
margin-left: $menu-icon-text-gap;
}
//菜单的文字以及hover颜色
.el-menu-item,
.el-submenu__title {
color: $head-menu-item-color;
&:hover {
color: $head-menu-item-hover-color;
}
> span {
max-width: 100px;
}
}
//submenu的右侧箭头会稍微偏上不懂为啥
.el-submenu__icon-arrow {
margin-top: -4px;
}
}
//顶部菜单的顶级节点
.el-menu--horizontal.el-menu {
//不显示折叠展开按钮
> .el-submenu > .el-submenu__title > .el-submenu__icon-arrow {
display: none;
}
//顶级节点的高度以及hover颜色
> .el-menu-item,
> .el-submenu > .el-submenu__title {
height: $nav-height;
line-height: $nav-height;
&:hover {
border-bottom: 2px solid $head-menu-item-hover-color;
}
}
}
/*-------顶部水平菜单结束---------*/

@ -24,3 +24,48 @@ export default {
}
}
</script>
<style lang="scss">
@import "~@/asset/style/variables.scss";
$logoSize: 30px;
.sidebar-logo-container {
position: relative;
width: 100%;
height: $nav-height;
line-height: $nav-height;
padding-left: 20px;
.sidebar-logo-link {
height: 100%;
width: 100%;
.sidebar-logo {
width: $logoSize;
height: $logoSize;
vertical-align: middle;
& + .sidebar-title {
margin-left: 12px;
}
}
.sidebar-title {
display: inline-block;
margin: 0;
color: #ffffff;
font-weight: 600;
line-height: $nav-height;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
}
&.collapse {
text-align: center;
padding-left: 0;
}
}
</style>

@ -0,0 +1,222 @@
<script type="text/jsx">
import menuMixin from "@/layout/mixin/menu"
import {getters as appGetters} from "@/layout/store/app"
import {getters as asideGetters, mutations as asideMutations} from "@/layout/store/aside"
import Logo from '@/layout/component/Aside/Logo'
import NavMenu from '@/component/menu/NavMenu'
import {getSidebarMenus, getActiveMenuByRoute} from "@/layout/util"
import {moveToActiveMenuVertically} from "@/util/element-ui/elMenu"
export default {
name: "Sidebar",
mixins: [menuMixin],
components: {Logo, NavMenu},
data() {
return {
//
mouseOutside: true
}
},
computed: {
isMobile: () => appGetters.isMobile,
//
menus: () => getSidebarMenus(),
//
renderInDrawer() {
return this.isMobile || asideGetters.autoHide
},
//truefalse
show() {
//store
if (asideGetters.show) return true
//false
if (this.isMobile) return false
//false
if (!asideGetters.autoHide) return false
//true
if (!this.mouseOutside) return true
// true
return this.collapse && this.openedMenuNum > 0
},
//truefalsepc
collapse() {
return asideGetters.collapse && !this.isMobile
},
//
shouldBindMouseMoveEvent() {
//false
if (this.isMobile) return false
//false
if (!asideGetters.autoHide) return false
//false
if (this.show) return false
//true
return this.mouseOutside
}
},
watch: {
'$route.path': {
immediate: true,
handler(v) {
//redirect
if (v.startsWith('/redirect')) return
this.activeMenu = getActiveMenuByRoute(this.$route)
const menu = this.$refs.menu
if (!menu) return
const item = menu.items[this.activeMenu]
//
if (!item) return menu.openedMenus = []
//elMenuinitOpenedMenu()select
this.onSelect(item.index, item.indexPath, item, false)
//
!this.renderInDrawer && this.$nextTick(this.moveToCurrentMenu)
}
},
//
isMobile: {
immediate: true,
handler(v) {
v && asideMutations.close()
}
},
//
show(v) {
v && this.$nextTick(this.moveToCurrentMenu)
},
//
shouldBindMouseMoveEvent: {
immediate: true,
handler(v) {
//
window.removeEventListener('mousemove', this.moveEvent)
v && window.addEventListener('mousemove', this.moveEvent)
}
}
},
methods: {
//
moveEvent(e) {
//
if (e.clientX <= 1) this.mouseOutside = false
},
//
onSelect(index, indexPath, item, jump = true) {
//
if (asideGetters.uniqueOpen && indexPath.length === 1) {
const menu = this.$refs.menu
const opened = menu.openedMenus
opened.forEach(i => i !== index && menu.closeMenu(i))
}
jump && this.actionOnSelectMenu(index)
//
if (this.renderInDrawer && this.show) {
asideMutations.close()
this.mouseOutside = true
}
},
//
moveToCurrentMenu() {
moveToActiveMenuVertically(this.$refs.menu)
}
},
beforeDestroy() {
window.removeEventListener('mousemove', this.moveEvent)
},
render() {
if (this.menus.length <= 0) return
const aside = (
<aside
class={{'aside': true, 'sidebar': true, 'collapse': this.collapse}}
on-mouseleave={() => this.mouseOutside = true}
on-mouseenter={() => this.mouseOutside = false}
>
{asideGetters.showLogo && <logo collapse={this.collapse}/>}
<nav-menu
menus={this.menus}
collapse={this.collapse}
default-active={this.activeMenu}
unique-opened={asideGetters.uniqueOpen}
show-parent={asideGetters.showParentOnCollapse}
switch-transition
on={{'select': this.onSelect, 'hook:mounted': this.watchOpenedMenus}}
/>
</aside>
)
if (this.renderInDrawer) {
return (
<el-drawer
visible={this.show}
with-header={false}
direction="ltr"
size="auto"
on-close={() => asideMutations.close()}
>
{aside}
</el-drawer>
)
}
return aside
}
}
</script>
<style lang="scss">
@import "~@/asset/style/variables.scss";
.sidebar {
display: flex;
flex-direction: column;
width: $aside-width;
background-color: $aside-menu-background;
font-size: 0;
height: 100vh;
z-index: 10;
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
transition: all 0.2s ease-in-out;
//
&.collapse {
width: $aside-icon-size + 20px * 2;
.menu-item-content {
display: none;
}
}
}
</style>

@ -1,12 +1,84 @@
<script>
<script type="text/jsx">
import RootSidebar from './root'
import SubSidebar from './sub'
export default {
name: "TwoPartSidebar",
data() {
return {}
},
methods: {},
mounted() {
functional: true,
render() {
return (
<aside class="aside">
<RootSidebar/>
<SubSidebar/>
</aside>
)
}
}
</script>
<style lang="scss">
@import "~@/asset/style/variables.scss";
$background-color: #1d2935;
.root-sidebar-container {
width: $aside-icon-size + 20px * 2;
position: relative;
}
.root-sidebar {
display: flex;
flex-direction: column;
position: absolute;
height: 100vh;
width: $aside-width;
background-color: $background-color;
overflow: hidden;
z-index: 11;
border-right: 1px solid #101117;
transition: all 0.2s ease-in-out;
> .el-menu--vertical.el-menu {
background-color: $background-color;
}
//
&.collapse {
width: $aside-icon-size + 20px * 2;
.menu-item-content {
display: none;
}
}
}
.sub-sidebar {
display: flex;
flex-direction: column;
width: $aside-width;
background-color: $aside-menu-background;
font-size: 0;
height: 100vh;
z-index: 10;
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
transition: all 0.2s ease-in-out;
//
&.collapse {
width: $aside-icon-size + 20px * 2;
.sub-sidebar-title,
.menu-item-content {
display: none;
}
}
&-title {
height: $nav-height;
line-height: $nav-height;
padding-left: 20px;
color: #ffffff;
font-size: 16px;
}
}
</style>

@ -1,6 +1,45 @@
<script type="text/jsx">
import menuMixin from "@/layout/mixin/menu"
import {getters as appGetters, mutations as appMutations} from "@/layout/store/app"
import {getters as asideGetters} from "@/layout/store/aside"
import Logo from '@/layout/component/Aside/Logo'
const Item = {
functional: true,
props: {
title: String,
icon: String,
active: Boolean
},
render(h, context) {
const {title, icon, active} = context.props
const {click} = context.listeners
const iconComponent =
icon
? <v-icon icon={icon}/>
: <i class="icon" style="font-style: normal">{title[0]}</i>
return (
<li
class={{'el-menu-item': true, 'is-active': active}}
on-click={click}
>
{iconComponent}
<span class="menu-item-content">{title}</span>
</li>
)
}
}
export default {
name: "TwoPartRootSidebar",
name: "RootSidebar",
mixins: [menuMixin],
components: {Logo, Item},
data() {
return {
@ -9,10 +48,66 @@ export default {
}
},
methods: {},
computed: {
menus() {
return appGetters.menus.map(root => ({...root, children: undefined}))
}
},
mounted() {
watch: {
//
$route: {
immediate: true,
handler(to) {
const {path, matched} = to
//使/redirect
if (path.startsWith('/redirect') || matched.length === 0) {
return
}
this.setActiveRootMenu(this.navMode, to)
}
}
},
methods: {
//
setActiveRootMenu(navMode = this.navMode, {matched} = this.$route) {
const rootPath = matched[0].path || '/'
appMutations.activeRootMenu(rootPath)
},
onSelect(index) {
//
if (index !== appGetters.activeRootMenu) {
this.actionOnSelectMenu(index)
}
//
this.mouseOutside = true
},
},
render() {
return (
<div class="root-sidebar-container">
<div
class={{'root-sidebar': true, 'collapse': this.mouseOutside}}
on-mouseleave={() => this.mouseOutside = true}
on-mouseenter={() => this.mouseOutside = false}
>
{asideGetters.showLogo && <logo collapse={this.mouseOutside}/>}
<ul class="el-menu el-menu--vertical">
{this.menus.map(({fullPath, meta: {title, icon}}) => (
<item
title={title}
icon={icon}
active={fullPath === appGetters.activeRootMenu}
on-click={() => this.onSelect(fullPath)}
/>
))}
</ul>
</div>
</div>
)
}
}
</script>

@ -1,20 +1,97 @@
<template>
<script type="text/jsx">
import menuMixin from "@/layout/mixin/menu"
import {getters as appGetters} from "@/layout/store/app"
import {getters as asideGetters} from "@/layout/store/aside"
import NavMenu from "@/component/menu/NavMenu"
import {getActiveMenuByRoute, getSidebarMenus} from "@/layout/util"
import {moveToActiveMenuVertically} from "@/util/element-ui/elMenu"
</template>
<script>
export default {
name: "TwoPartSubSidebar",
data() {
return {}
name: "SubSidebar",
mixins: [menuMixin],
components: {NavMenu},
computed: {
//
rootMenu() {
const active = appGetters.activeRootMenu
return appGetters.menus.find(i => i.fullPath === active)
},
//
menus: () => getSidebarMenus(),
//truefalsepc
collapse() {
return asideGetters.collapse && !asideGetters.isMobile
},
},
watch: {
'$route.path': {
immediate: true,
handler(v) {
//redirect
if (v.startsWith('/redirect')) return
this.activeMenu = getActiveMenuByRoute(this.$route)
const menu = this.$refs.menu
if (!menu) return
const item = menu.items[this.activeMenu]
//
if (!item) return menu.openedMenus = []
//elMenuinitOpenedMenu()select
this.onSelect(item.index, item.indexPath, item, false)
//
this.$nextTick(this.moveToCurrentMenu)
}
}
},
methods: {
//
onSelect(index, indexPath, item, jump = true) {
//
if (asideGetters.uniqueOpen && indexPath.length === 1) {
const menu = this.$refs.menu
const opened = menu.openedMenus
opened.forEach(i => i !== index && menu.closeMenu(i))
}
jump && this.actionOnSelectMenu(index)
},
//
moveToCurrentMenu() {
moveToActiveMenuVertically(this.$refs.menu)
}
},
methods: {},
mounted() {
render() {
if (this.menus.length <= 0) return
return (
<div class={{'sub-sidebar': true, 'collapse': this.collapse}}>
<div class="sub-sidebar-title">
{this.rootMenu && this.rootMenu.meta.title}
</div>
<nav-menu
menus={this.menus}
collapse={this.collapse}
default-active={this.activeMenu}
unique-opened={asideGetters.uniqueOpen}
show-parent={asideGetters.showParentOnCollapse}
switch-transition
on-select={this.onSelect}
/>
</div>
)
}
}
</script>
<style scoped>
</style>

@ -1,208 +1,48 @@
<script type="text/jsx">
import menuMixin from "@/layout/mixin/menu"
import OnePart from './OnePart'
import TwoPart from './TwoPart'
import {getters as appGetters} from "@/layout/store/app"
import {getters as asideGetters, mutations as asideMutations} from "@/layout/store/aside"
import Logo from '@/layout/component/Aside/Logo'
import NavMenuItem from '@/component/menu/NavMenu/item'
import {getSidebarMenus, getActiveMenuByRoute} from "@/layout/util"
import {moveToActiveMenuVertically} from "@/util/element-ui/elMenu"
export default {
name: 'Aside',
functional: true,
mixins: [menuMixin],
components: {Logo, NavMenuItem},
data() {
return {
//
mouseOutside: true
}
},
computed: {
isMobile: () => appGetters.isMobile,
//
menus: () => getSidebarMenus(),
//
renderInDrawer() {
return this.isMobile || asideGetters.autoHide
},
//truefalse
show() {
//store
if (asideGetters.show) return true
//false
if (this.isMobile) return false
//false
if (!asideGetters.autoHide) return false
//true
if (!this.mouseOutside) return true
// true
return this.collapse && this.openedMenuNum > 0
},
//truefalsepc
collapse() {
return asideGetters.collapse && !this.isMobile
},
//
shouldBindMouseMoveEvent() {
//false
if (this.isMobile) return false
//false
if (!asideGetters.autoHide) return false
//false
if (this.show) return false
//true
return this.mouseOutside
}
},
watch: {
'$route.path': {
immediate: true,
handler(v) {
//redirect
if (v.startsWith('/redirect')) return
this.activeMenu = getActiveMenuByRoute(this.$route)
const menu = this.$refs.menu
if (!menu) return
const item = menu.items[this.activeMenu]
//
if (!item) return menu.openedMenus = []
//elMenuinitOpenedMenu()select
this.onSelect(item.index, item.indexPath, item, false)
//
!this.renderInDrawer && this.$nextTick(this.moveToCurrentMenu)
}
},
//
isMobile: {
immediate: true,
handler(v) {
v && asideMutations.close()
}
},
//
show(v) {
v && this.$nextTick(this.moveToCurrentMenu)
},
//
shouldBindMouseMoveEvent: {
immediate: true,
handler(v) {
//
window.removeEventListener('mousemove', this.moveEvent)
v && window.addEventListener('mousemove', this.moveEvent)
}
render() {
//使
if (appGetters.isMobile) {
return <OnePart/>
}
},
methods: {
//
moveEvent(e) {
//
if (e.clientX <= 1) this.mouseOutside = false
},
//
onSelect(index, indexPath, item, jump = true) {
//
if (asideGetters.uniqueOpen && indexPath.length === 1) {
const menu = this.$refs.menu
const opened = menu.openedMenus
opened.forEach(i => i !== index && menu.closeMenu(i))
}
jump && this.actionOnSelectMenu(index)
//
if (this.renderInDrawer && this.show) {
asideMutations.close()
this.mouseOutside = true
}
},
//
moveToCurrentMenu() {
moveToActiveMenuVertically(this.$refs.menu)
switch (appGetters.navMode) {
case 'mix':
case 'aside':
return <OnePart/>
case 'aside-two-part':
return <TwoPart/>
}
},
beforeDestroy() {
window.removeEventListener('mousemove', this.moveEvent)
},
}
}
</script>
render() {
if (this.menus.length <= 0) return
<style lang="scss">
.aside {
display: flex;
position: relative;
}
const aside = (
<aside
class={{'aside': true, 'collapse': this.collapse}}
on-mouseleave={() => this.mouseOutside = true}
on-mouseenter={() => this.mouseOutside = false}
>
{asideGetters.showLogo && <logo collapse={this.collapse}/>}
<el-menu
ref="menu"
class="el-menu--vertical"
collapse={this.collapse}
collapse-transition={false}
default-active={this.activeMenu}
unique-opened={asideGetters.uniqueOpen}
on={{'select': this.onSelect, 'hook:mounted': this.watchOpenedMenus}}
>
{this.menus.map(m => (
<nav-menu-item
menu={m}
show-parent={asideGetters.showParentOnCollapse}
collapse={this.collapse}
show-icon-max-depth={1}
/>
))}
</el-menu>
</aside>
)
/* 侧边栏切换动画开始 */
.sidebar-enter-active {
transition: all 0.2s;
}
if (this.renderInDrawer) {
return (
<el-drawer
visible={this.show}
with-header={false}
direction="ltr"
size="auto"
on-close={() => asideMutations.close()}
>
{aside}
</el-drawer>
)
}
.sidebar-enter,
.sidebar-leave-active {
opacity: 0;
transform: translateY(30px) skewY(10deg)
}
return aside
}
.sidebar-leave-active {
position: absolute;
}
</script>
<style lang="scss" src="./style.scss"></style>
/* 侧边栏切换动画结束 */
</style>

@ -5,6 +5,7 @@
*/
import menuMixin from "@/layout/mixin/menu"
import {getters as appGetters, mutations as appMutations} from "@/layout/store/app"
import NavMenu from "@/component/menu/NavMenu"
import NavMenuItem from "@/component/menu/NavMenu/item"
import {getActiveMenuByRoute} from "@/layout/util"
@ -13,7 +14,7 @@ export default {
mixins: [menuMixin],
components: {NavMenuItem},
components: {NavMenu, NavMenuItem},
props: {
//
@ -190,15 +191,14 @@ export default {
}
return (
<el-menu
ref="menu"
<nav-menu
mode="horizontal"
default-active={this.activeMenu}
on-select={this.onSelect}
>
{this.renderVisibleMenus(visibleMenus)}
{this.renderHiddenMenus(hiddenMenus, hiddenMenus.length === menus.length)}
</el-menu>
</nav-menu>
)
}
}

@ -42,13 +42,14 @@ export default {
//
//
//
//
//
//
//
const hasSidebarMenus = getSidebarMenus().length > 0,
isMobile = appGetters.isMobile,
correctMode = ['aside','mix'].includes(appGetters.navMode),
notAutoHidden = !asideGetters.autoHide,
renderHamburger = hasSidebarMenus && (isMobile || correctMode && notAutoHidden)
correctMode =
['aside', 'mix'].includes(appGetters.navMode) && !asideGetters.autoHide
|| appGetters.navMode === 'aside-two-part',
renderHamburger = hasSidebarMenus && (isMobile || correctMode)
if (renderHamburger) {
const active = isMobile ? asideGetters.show : !asideGetters.collapse
@ -123,4 +124,53 @@ export default {
}
</script>
<style lang="scss" src="./style.scss"></style>
<style lang="scss">
@import "~@/asset/style/variables.scss";
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
height: $nav-height;
padding: 0 12px;
transition: height .3s ease-in-out;
position: relative;
z-index: 9;
background-color: #ffffff;
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
> div {
display: flex;
flex-wrap: nowrap;
height: 100%;
}
.navbar-icon {
font-size: 18px;
}
.navbar-item {
display: flex;
align-items: center;
padding: 0 8px;
color: #5a5e66;
transition: background .3s;
cursor: pointer;
&:hover {
background: rgba(0, 0, 0, .025)
}
}
.avatar-wrapper {
display: flex;
align-items: center;
span {
margin-right: 5px;
font-size: 18px;
}
}
}
</style>

@ -1,101 +0,0 @@
@import "~@/asset/style/variables.scss";
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
height: $nav-height;
padding: 0 12px;
transition: height .3s ease-in-out;
position: relative;
z-index: 9;
background-color: #ffffff;
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
> div {
display: flex;
flex-wrap: nowrap;
height: 100%;
}
.navbar-icon {
font-size: 18px;
}
.navbar-item {
display: flex;
align-items: center;
padding: 0 8px;
color: #5a5e66;
transition: background .3s;
cursor: pointer;
&:hover {
background: rgba(0, 0, 0, .025)
}
}
.avatar-wrapper {
display: flex;
align-items: center;
span {
margin-right: 5px;
font-size: 18px;
}
}
}
//顶部水平菜单
.el-menu--horizontal .el-menu,
.el-menu--horizontal.el-menu {
font-size: 14px;
.icon {
font-size: 14px;
}
//图标和文字的间隔
.icon + .menu-item-content {
margin-left: $menu-icon-text-gap;
}
//菜单的文字以及hover颜色
.el-menu-item,
.el-submenu__title {
color: $head-menu-item-color;
&:hover {
color: $head-menu-item-hover-color;
}
> span {
max-width: 100px;
}
}
//submenu的右侧箭头会稍微偏上不懂为啥
.el-submenu__icon-arrow {
margin-top: -4px;
}
}
//顶部菜单的顶级节点
.el-menu--horizontal.el-menu {
//不显示折叠展开按钮
> .el-submenu > .el-submenu__title > .el-submenu__icon-arrow {
display: none;
}
//顶级节点的高度以及hover颜色
> .el-menu-item,
> .el-submenu > .el-submenu__title {
height: $nav-height;
line-height: $nav-height;
&:hover {
border-bottom: 2px solid $head-menu-item-hover-color;
}
}
}

@ -1,7 +1,7 @@
<script type="text/jsx">
import {getters as tagsViewGetters} from "@/layout/store/tagsView"
import VNavbar from './component/Navbar'
import TagsView from './component/TagsView'
import VNavbar from './Navbar'
import TagsView from './TagsView'
export default {
name: "Header",

@ -6,21 +6,25 @@ export function getRouterViewCacheKey({name, path, fullPath, meta = {}}) {
return usePathKey ? path : useFullPathKey ? fullPath : name
}
//获取侧边栏的菜单
//获取侧边栏的菜单,如果是双层侧边栏导航时,获取的是子菜单
export function getSidebarMenus() {
const menus = appGetters.menus
if (!Array.isArray(menus)) {
return []
}
//移动端时,侧边栏只会按侧边栏导航模式渲染
if (appGetters.isMobile) {
return menus
}
switch (appGetters.navMode) {
case 'aside':
case 'aside-two-part':
return menus
case 'head':
return []
case 'aside-two-part':
case 'mix':
const root = menus.find(i => i.path === appGetters.activeRootMenu)
return root ? root.children || [] : []

Loading…
Cancel
Save