最近在做一个基于vue+element的后台管理系统 做了一个可伸缩的 侧边栏 记录下 在很多管理系统都能用到 。
首先是收起时候
1. 做的过程中折叠出现的问题:
- 没有子菜单折叠时,icon会隐藏
- 有子菜单折叠时,箭头不隐藏
解决:
- treemenu.vue 中没有子菜单时,比如侧边栏的首页就没有子菜单,去掉
<template slot="title">
就好了 - 箭头不隐藏问题,在sidebar.vue中增加样式
.el-icon-arrow-right { display: none; }
2. 发现侧边栏跳转不了问题:
重点提示:
必须设置:default-active="$route.name"
和:router="true"
- el-submenu之 index属性: 这个index表示每一组的唯一标志,当我们定义了
unique-opened=true
的时候会根据这个标识展示相应的选项。自己可以测试一下把所有的选项组的index都设置成同一个值得时候是什么效果就明白了这个标志得作用。 - el-menu-item 之index属性:这个index值会被作为跳转路径进行跳转,
我们需要把这个值和页面路径对应起来
。所以需要开启路由模式
,点击哪个页面的时候左侧就会显示哪个页面内容信息。
3. 递归生成侧边栏
有一个菜单树,顶层菜单下面有多个子菜单,子菜单下还有子菜单。。。
这时候就要用递归处理。我现在项目里还没有这个需求,但防止后面需求会有,我还是用递归做的侧边栏
首先是新建一个sidebar.vue
<template>
<el-aside :width="isCollapse ? '64px' : '200px'" id="sidebar" class="sidebar">
<el-scrollbar class="scrollbar-wrapper">
<div class="el-icon-user-solid subhead-headImg">
<div>{{ username }}</div>
</div>
<div class="toggle-button" @click="toggleCollapse">|||</div>
<!-- 侧边栏菜单区域 -->
<el-menu
background-color="#333d54"
text-color="rgba(255,255,255,0.5)"
active-text-color="rgba(255,255,255)"
:default-active="$route.name"
@select="handleSel"
:collapse="isCollapse"
:collapse-transition="false"
:unique-opened="true"
:router="true"
v-if="sidebarList"
>
<div v-for="(item, index) in sidebarList" :key="index">
<TreeMenu :treedata="item"></TreeMenu>
</div>
</el-menu>
</el-scrollbar>
</el-aside>
</template>
<script>
import path from "path";
import sideBar from "@/meta/sidebar";
import TreeMenu from "@/components/tree/treemenu";
export default {
name: "Sidebar",
components: {
TreeMenu
},
data() {
return {
// 是否折叠
isCollapse: false,
openMenu: [],
username: ""
};
},
computed: {
sidebarList() {
return sideBar.mainbar();
}
},
methods: {
handleSel(key, keyPath) {
console.log(path.resolve(process.cwd(), ...keyPath));
let sitePath = path.resolve(process.cwd(), ...keyPath);
this.$router.push({ path: sitePath });
},
// 点击按钮,切换菜单的折叠与展开
toggleCollapse() {
this.isCollapse = !this.isCollapse;
}
},
created() {
// this.setSidebarList('mainbar')
this.sidebarList.forEach(item => {
this.openMenu.push(item.key);
});
},
mounted() {
this.username = sessionStorage.getItem("username");
},
watch: {
sidebarList() {
if (this.sidebarList) {
this.sidebarList.forEach(item => {
this.openMenu.push(item.key);
});
}
}
}
};
</script>
<style lang="scss" scope>
.sidebar {
height: 100%;
}
.toggle-button {
background-color: #4a5064;
font-size: 10px;
line-height: 24px;
color: #fff;
text-align: center;
letter-spacing: 0.2em;
cursor: pointer;
}
// 隐藏箭头
.el-icon-arrow-right {
display: none;
}
</style>
treemenu.vue
<template>
<div>
<el-submenu
v-if="treedata.child && treedata.child.length > 0"
:index="treedata.key"
>
<template slot="title">
<i :class="treedata.ico" v-if="treedata.ico"></i>
<span slot="title">{{ treedata.value }}</span>
</template>
<div v-for="(children, index) in treedata.child" v-bind:key="index">
<!--递归调用自身,这里主要根据name的名字-->
<treeItem :treedata="children"></treeItem>
</div>
</el-submenu>
<el-menu-item v-else :index="treedata.key">
<i :class="treedata.ico" v-if="treedata.ico"></i>
<span slot="title">{{ treedata.value }}</span>
</el-menu-item>
</div>
</template>
<script>
export default {
name: "treeItem",
props: ["treedata"],
data() {
return {};
}
};
</script>
<style lang="scss" scoped>
/*隐藏文字*/
.el-menu--collapse .el-submenu__title span {
display: none;
}
</style>
sidebar.js
const staticBar = [
{
key: 'index',
ico: 'el-icon-document',
value: '导航一',
},
{
key: 'permission',
ico: 'el-icon-data-line',
value: '导航二',
child:[{
key: 'adminlist',
ico: 'el-icon-document',
value: '选项1',
},
{
key: 'role',
ico: 'el-icon-document',
value: '选项2',
},
{
key: 'authManage',
ico: 'el-icon-document',
value: '选项3',
}]
},
{
key: 'member',
ico: 'el-icon-printer',
value: '导航三',
child:[{
key: '/member/memberList',
ico: 'el-icon-document',
value: '选项1',
},
{
key: '/member/memberSearch',
ico: 'el-icon-document',
value: '选项2',
},
{
key: 'New_business',
ico: 'el-icon-document',
value: '选项3',
},
{
key: 'Real_name',
ico: 'el-icon-document',
value: '选项4',
},
{
key: 'invitation',
ico: 'el-icon-document',
value: '选项5',
}]
},
]
最终实现折叠效果: