<template>
<div
class="sidebar gey-bg-2"
:class="{
'sm-sidebar': !isExpand,
'hover-sidebar': !isExpand && isHover,
'isOrder-sidebar': $route.meta.isOrder
}"
@mouseenter="overSidebar"
@mouseleave="leaveSidebar">
<div class="container">
<template v-for="(item, index) in menu">
<!-- 有子菜单 -->
<div class="item gey-hover gey-sidebar-font" :class="!isExpand ?'additional-width':''" :key="item.name">
<div
@click="toggleMenu(index, item)"
@mouseenter="enterItem(index)"
@mouseleave="leaveItem(index)"
class="item-inner"
:class="{
'active':
curHoverItemIndex === index || item.active
}">
<span class="left">
<span class="icon-box">
<navigation-icon :name="item.icon"></navigation-icon>
<ul class="additional" :class="{ 'item-hover': curHoverItemIndex === index}" v-if="!isExpand && item.subMenu.length>0">
<template v-for="subItem in item.subMenu">
<li :key="subItem.title" @click="clickMenu(subItem)" class="gey-sidebar-sub-font" v-if="!subItem.hidden">
<div class="link"
:class="{
'router-active': subItem.route.name === $route.name ||subItem.route.name === $route.meta.fromCategory }">
<span class="sub-name">{{subItem.name}}</span>
<span class="new-flag" v-if="subItem.isNew">new</span>
<span class="new-flag" v-if="subItem.isHot">hot</span>
</div>
</li>
</template>
</ul>
</span>
<span class="title" v-if="isExpand">{{item.name}}</span>
</span>
<i class="iconfont icon-tubiaozhizuo-" :class="{'active': item.toggle}" v-if="item.subMenu.length > 0 && isExpand"></i>
</div>
<ul
class="submenu"
v-if="isExpand"
:style="{
'height': item.toggle ? item.subMenu.length * 44 + 'px' : '0px',
'opacity': item.toggle ? 1 : 0
}">
<template v-for="subItem in item.subMenu">
<li :key="subItem.title" @click="clickMenu(subItem)" class="gey-sidebar-sub-font" v-if="!subItem.hidden">
<div
class="link"
:class="{
'router-active':
subItem.route.name === $route.name ||
subItem.route.name === $route.meta.fromCategory
}"
>
<span class="sub-name">{{subItem.name}}</span>
<span class="new-flag" v-if="subItem.isNew">new</span>
<span class="new-flag" v-if="subItem.isHot">hot</span>
</div>
</li>
</template>
</ul>
</div>
</template>
</div>
</div>
</template>
<script>
import allMenu from './newMenu.js'
import navigationIcon from '@/components/frontZone/navigationIcon' // 直播带货看板
export default {
data () {
return {
isOver: false,
timeout: null,
menu: [],
interval: null,
curRouteName: '',
curHoverItemIndex: 1
}
},
mounted () {
this.getMenu()
let menu = this.menu
for (let k = 0; k < menu.length; k++) {
if (this.$route.name === menu[k].route.name) {
menu[k].toggle = true
break
}
for (let i = 0; i < menu[k].subMenu.length; i++) {
if (this.$route.name === menu[k].subMenu[i].route.name || this.$route.meta.fromCategory === menu[k].subMenu[i].route.name) {
menu[k].toggle = true
break
} else {
menu[k].toggle = false
}
}
}
},
beforeDestroy () {
clearInterval(this.interval)
},
computed: {
isExpand () {
return this.$store.state.common.isExpand
},
isHover () {
return this.$store.state.common.isHover
},
userInfo () {
return this.$store.state.user.userInfo
},
fdRoleCode () {
return this.$store.state.user.userInfo && this.$store.state.user.userInfo.fdRoleCode
}
},
watch: {
'$route' (newVal, oldVal) {
if (newVal !== oldVal) {
let menu = this.menu
this.menu.forEach((item) => {
item.active = false
})
for (let k = 0; k < menu.length; k++) {
if (this.$route.name === menu[k].route.name) {
menu[k].toggle = true
menu[k].active = true
break
}
for (let i = 0; i < menu[k].subMenu.length; i++) {
if (this.$route.name === menu[k].subMenu[i].route.name || this.$route.meta.fromCategory === menu[k].subMenu[i].route.name) {
menu[k].toggle = true
menu[k].active = true
break
} else {
menu[k].toggle = false
menu[k].active = false
}
}
}
}
}
},
methods: {
getMenu () {
let menu = allMenu()
for (let k = 0; k < menu.length; k++) {
if (this.$route.name === menu[k].route.name) {
menu[k].active = true
break
}
for (let i = 0; i < menu[k].subMenu.length; i++) {
if (this.$route.name === menu[k].subMenu[i].route.name) {
menu[k].active = true
break
} else {
menu[k].active = false
}
}
}
this.menu = menu
this.manuScroll()
},
clickMenu (item, index) {
if (item.route.name === 'smartSearch') {
let {href} = this.$router.resolve({name: 'smartSearch'})
window.open(href, '_blank')
} else {
this.$router.push(item.route)
}
this.curRouteName = item.route.name
},
manuScroll () {
this.interval = setTimeout(() => {
if (document.querySelector('.item .router-active')) {
document.querySelector('.item .router-active').scrollIntoView(false)
clearTimeout(this.interval)
} else {
this.manuScroll()
}
}, 200)
},
toggleMenu (index, item) {
if (item.subMenu.length > 0) {
this.$set(this.menu, index, Object.assign({}, item, {toggle: !this.menu[index].toggle}))
} else {
this.$router.push(item.route)
}
},
overSidebar () {
this.$store.dispatch('hoverSidebar', true)
},
leaveSidebar () {
this.$store.dispatch('hoverSidebar', false)
},
enterItem (index) {
this.curHoverItemIndex = index
},
leaveItem (index) {
this.curHoverItemIndex = 1000
}
},
components: {
navigationIcon
}
}
</script>
<style lang="scss" scoped>
@import 'assets/styles/theme-mixin.scss';
.sub-name {
font-size: 14px;
}
.isOrder-sidebar {
.link {
&.router-active, &:hover {
.sub-name {
font-size: 14px;
font-weight: bold;
}
&::before {
.sub-name {
font-size: 14px;
font-weight: bold;
}
}
}
}
}
.new-flag {
position: absolute;
width: 30px;
height: 16px;
line-height: 16px;
font-size: 12px;
color: #ffffff;
text-align: center;
border-radius: 4px;
}
.sidebar {
position: fixed;
top: 50px;
left: 0;
width: 210px;
bottom: 0;
z-index: 11;
transition: all .8s cubic-bezier(.21, .83, .49, 1);
&.sm-sidebar {
transform: translateX(-159px);
.container {
.item {
transform: translate3d(142px, 0, 0);
}
.additional-width{
width: 50px;
}
}
&.hover-sidebar {
/*transform: translateX(0px);*/
/*.container {*/
/*.item {*/
/*transform: translate3d(0px,0,0);*/
/*}*/
/*}*/
}
}
.container {
padding-top: 24px;
height: 100%;
.item {
width: 200px;
position: relative;
}
.item-inner {
height: 45px;
padding: 0 12px 0 30px;
margin-bottom: 4px;
display: flex;
align-items: center;
justify-content: space-between;
transition: all .6s cubic-bezier(.21, .83, .49, 1);
cursor: pointer;
.left {
position: relative;
display: flex;
align-items: center;
.new-flag {
right: -29px;
top: -2px;
}
.icon-box {
width: 30px;
margin-right: 8px;
text-align: center;
position: relative;
.additional {
transition: all 0.3s ease;
background: #FFFFFF;
box-shadow: 6px 2px 20px rgba(0, 0, 0, 0.1);
position: absolute;
transform: translateX(38px);
top: -15px;
display: none;
padding: 20px;
& li{
margin-bottom: 24px;
font-size: 14px;
text-align: left;
white-space: nowrap;
}
& li:last-child{
margin-bottom: 0px;
}
}
.item-hover{
display: block;
}
}
.title {
font-size: 16px;
font-weight: bold;
&.no-submenu-title {
position: relative;
.new-flag {
top: -14px;
right: -30px;
}
}
}
}
.iconfont {
display: inline-block;
color: #B8BBBF;
transition: all 0.4s;
transform-origin: center center;
font-size: 12px;
&.active {
transform: rotate(180deg);
}
}
&.active, &.router-active {
.icon-img {
animation: iconPop 1s ease-in-out;
}
}
}
.router-active .sub-name {
font-size: 14px;
font-weight: bold;
}
.router-active:hover .sub-name {
font-size: 14px;
font-weight: bold;
}
.submenu {
transition: all 0.4s;
li {
.link {
position: relative;
width: 100%;
display: inline-block;
padding-left: 68px;
height: 42px;
line-height: 42px;
cursor: pointer;
.title {
vertical-align: middle;
}
&:before {
display: none;
position: absolute;
content: "";
width: 4px;
left: 0;
top: 0;
height: 100%;
}
&.router-active, &:hover {
/*background-color: #d9d4d4;*/
/*// color: var(--th-sidebar-font-active-color) !important;*/
/*.sub-name{*/
/*}*/
&:before {
display: inline-block;
}
}
}
}
}
}
}
@keyframes iconPop {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(0.2);
opacity: 0;
}
75% {
transform: scale(1.2);
opacity: 1;
}
100% {
transform: scale(1);
opacity: 1;
}
}
.en-app {
.sidebar .container, .hover-sidebar .container {
.item-inner {
padding-left: 20px;
}
.submenu li .link {
padding-left: 50px;
.new-flag {
left: 22px;
}
}
}
.sidebar .container .item-inner {
padding-left: 20px;
}
.sidebar.sm-sidebar {
.container .item-inner .left .icon-box {
margin: 0 15px 0 10px;
}
}
}
.scroll-bar-box {
@include scroll-bar-box(100vh);
height: 100vh;
}
.title, .sub-name, .svg-icons {
transition: 0.1s ease;
}
</style>