目录
实现效果
展开效果图:

合并效果图:
1、思路
- 点击按钮(展开与折叠按钮),触发左侧菜单栏的张开与折叠,需要使用一个变量(state.sidebar.opened)来控制
- 为什么要用 state.sidebar.opened 全局变量? 原因是按钮组件与侧边栏组件不是父子组件的关系,按钮点击事件改变 state.sidebar.opened 值为 true 或 false。侧边栏组件需要读取 state.sidebar.opened 来决定自己是要展开还是折叠?
- 左侧 el-menu 组件中有 collapse 属性是控制菜单栏的展开与收缩。我们可以通过 state.sidebar.opened 值,来控制 el-menu元素
- 只是设置 el-menu 中 collapse 属性还是不够的, 还需要配置 左边侧边栏的隐藏样式, 通过state.sidebar.opened 动态显示样式
2、按钮单击事件
在 src / components / Hamburger / index.vue (按钮组件) 中
新增单击事件
<div style="padding: 0 15px;" @click="toggleClick">
单击事件中调用父组件方法
toggleClick() {
this.$emit('toggleClick')
}
具体代码:
<template>
<div style="padding: 0 15px;" @click="toggleClick">
<svg
:class="{'is-active':isActive}"
class="hamburger"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
>
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
</svg>
</div>
</template>
<script>
export default {
name: 'Hamburger',
props: {
isActive: {
type: Boolean,
default: false
}
},
methods: {
toggleClick() {
this.$emit('toggleClick')
}
}
}
</script>
<style scoped>
.hamburger {
display: inline-block;
vertical-align: middle;
width: 20px;
height: 20px;
}
.hamburger.is-active {
transform: rotate(180deg);
}
</style>
3、父组件调用 Vuex 改变侧边栏状态
在 src / layout / components / Navbar.vue 中
子组件调用父组件方法:
<hamburger class="hamburger-container" @toggleClick="toggleSideBar"/>
父组件调用 vuex 改变state.sidebar.opened 的值
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
}
具体代码:
<template>
<div class="navbar">
<hamburger class="hamburger-container" @toggleClick="toggleSideBar"/>
</div>
</template>
<script type="text/ecmascript-6">
import Hamburger from '@/components/Hamburger'
export default {
data() {
return {}
},
components: {
Hamburger
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
}
}
}
</script>
<style lang="scss" scoped>
.navbar {
height: 50px;
overflow: hidden;
position: relative;
background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container {
line-height: 46px;
height: 100%;
float: left;
cursor: pointer;
transition: background 0.3s;
-webkit-tap-highlight-color: transparent;
&:hover {
background: rgba(0, 0, 0, 0.025);
}
}
}
</style>
4、新建app模块用于管理整个应用状态
新建 src / store / modules / app.js 内容为:
import Cookies from 'js-cookie'
const state = {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
}
}
const mutations = {
TOGGLE_SIDEBAR: state => {
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
}
}
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
5、左侧菜单栏
在 src / layout / components / Sidebar / index.vue 中
控制 el-menu 的展开和折叠
<el-menu :collapse="isCollapse" />
isCollapse方法:
isCollapse() {
return !this.sidebar.opened
}
具体代码:
<template>
<div class="">
<el-scrollbar class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="variables.menuBg"
:text-color="variables.menuText"
:unique-opened="true"
:active-text-color="variables.menuActiveText"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item
v-for="route in permission_routes"
:key="route.path"
:item="route"
:base-path="route.path"
></sidebar-item>
</el-menu>
</el-scrollbar>
</div>
</template>
<script type="text/ecmascript-6">
import { mapGetters } from 'vuex'
import SidebarItem from './SidebarItem'
import variables from '@/assets/styles/variables.scss'
export default {
data() {
return {}
},
components: { SidebarItem },
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath)
},
handleClose(key, keyPath) {
console.log(key, keyPath)
}
},
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
},
variables() {
return variables
},
isCollapse() {
return !this.sidebar.opened
}
}
}
</script>
<style lang="scss" scoped>
</style>
6、隐藏样式
在 src / assets / styles / sidebar.scss 中, 新增隐藏样式
#app {
.main-container {
min-height: 100%;
transition: margin-left .28s;
margin-left: $sideBarWidth;
position: relative;
}
.sidebar-container {
width: $sideBarWidth !important;
background-color: $menuBg;
height: 100%;
position: fixed;
font-size: 0px;
top: 0;
bottom: 0;
left: 0;
overflow: hidden;
.scrollbar-wrapper {
height: 100%;
overflow-x: hidden !important;
.el-scrollbar__wrap {
overflow-x: hidden !important;
}
a {
display: inline-block;
width: 100%;
overflow: hidden;
text-decoration: none;
}
.el-menu {
border: none;
height: 100%;
width: 100% !important;
}
.svg-icon {
margin-right: 16px;
}
}
}
.hideSidebar {
.sidebar-container {
width: 54px !important;
}
.main-container {
margin-left: 54px;
}
.submenu-title-noDropdown {
padding: 0 !important;
position: relative;
.el-tooltip {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
}
}
.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;
}
}
}
}
}
}
本文介绍了在Vue项目中如何实现左侧菜单栏的展开与折叠功能。通过使用Vuex管理全局状态,当点击按钮时,改变`state.sidebar.opened`的值,进而控制`el-menu`的`collapse`属性和侧边栏的隐藏样式,实现了菜单栏的动态切换效果。

2万+

被折叠的 条评论
为什么被折叠?



