vue实现动态侧边栏
实现动态侧边栏的核心思路
动态侧边栏通常基于路由配置或权限数据动态生成菜单项,核心是通过v-for循环渲染菜单结构,结合vue-router实现导航功能。以下是具体实现方法:
基础路由配置
在router/index.js中定义路由时添加meta信息作为菜单元数据:
const routes = [
{
path: '/dashboard',
component: Dashboard,
meta: { title: '控制台', icon: 'el-icon-monitor', requiresAuth: true }
},
{
path: '/user',
component: User,
meta: { title: '用户管理', icon: 'el-icon-user' }
}
]
侧边栏组件实现
创建Sidebar.vue组件,通过$router.options.routes获取路由配置:
<template>
<el-menu
:default-active="$route.path"
router
unique-opened
>
<template v-for="route in permissionRoutes">
<el-submenu
v-if="route.children"
:key="route.path"
:index="route.path"
>
<template #title>
<i :class="route.meta.icon"></i>
<span>{{ route.meta.title }}</span>
</template>
<el-menu-item
v-for="child in route.children"
:key="child.path"
:index="child.path"
>
{{ child.meta.title }}
</el-menu-item>
</el-submenu>
<el-menu-item
v-else
:key="route.path"
:index="route.path"
>
<i :class="route.meta.icon"></i>
<span>{{ route.meta.title }}</span>
</el-menu-item>
</template>
</el-menu>
</template>
<script>
export default {
computed: {
permissionRoutes() {
return this.$router.options.routes.filter(route => {
return route.meta && !route.meta.hidden
})
}
}
}
</script>
权限控制实现
结合权限系统动态过滤菜单,通常在store中处理:
// store/modules/permission.js
const filterRoutes = (routes, roles) => {
return routes.filter(route => {
if (hasPermission(roles, route)) {
if (route.children) {
route.children = filterRoutes(route.children, roles)
}
return true
}
return false
})
}
菜单状态持久化
使用localStorage或vuex-persistedstate保存菜单展开状态:
// 在侧边栏组件中
watch: {
'$route'() {
localStorage.setItem('sidebarStatus', this.isCollapse ? '1' : '0')
}
}
响应式处理
添加响应式折叠功能:
<el-menu
:collapse="isCollapse"
@select="handleSelect"
>
<div class="toggle-button" @click="toggleCollapse">
|||
</div>
</el-menu>
<script>
export default {
data() {
return {
isCollapse: false
}
},
methods: {
toggleCollapse() {
this.isCollapse = !this.isCollapse
}
}
}
</script>
多级菜单优化
处理无限嵌套菜单时,可采用递归组件:
<template>
<el-submenu v-if="hasChildren" :index="item.path">
<template #title>{{ item.meta.title }}</template>
<sidebar-item
v-for="child in item.children"
:key="child.path"
:item="child"
/>
</el-submenu>
<el-menu-item v-else :index="item.path">
{{ item.meta.title }}
</el-menu-item>
</template>
<script>
export default {
name: 'SidebarItem',
props: {
item: Object
},
computed: {
hasChildren() {
return this.item.children && this.item.children.length > 0
}
}
}
</script>
样式优化建议
添加过渡动画和自定义样式:
.el-menu {
border-right: none;
transition: width 0.3s;
}
.el-menu--collapse {
width: 64px;
}
.menu-title {
transition: opacity 0.3s;
}
.el-menu--collapse .menu-title {
opacity: 0;
}
以上实现方案可根据具体项目需求进行调整,核心在于将路由配置与组件渲染解耦,通过权限系统控制菜单可见性,结合状态管理实现持久化功能。







