我正在 VueJS 中创建一个侧边栏组件以用于学习目的。我正在尝试开发一个拆分菜单,因此左侧有图标,单击它会展开侧边栏的右侧部分并在那里加载该内容。我正在努力解决两件事:
首先,我添加了一些逻辑,以便如果单击该图标,它将添加一个活动类以通过检查它与从数据集生成的键来突出显示它。我的问题是我需要添加逻辑,以便如果单击图标并且它不是活动图标,它将添加活动类,然后还将活动类添加到右侧边栏,以便扩展它。但是,如果图标处于活动状态,则再次单击它应该通过从中删除活动类来折叠右侧边栏。
其次,我不确定将内容加载到右侧边栏中的最佳方法是什么。对于大多数图标,它们将生成特定于该图标类别的特定路由器/链接导航,但某些图标可能会加载更复杂的项目,例如其中的聊天模板。解决这个问题的最佳方法是什么。我正在考虑通过在 data() 字段数组中使用另一层来添加右侧模板,但我不确定这是否是开发组件的最佳实践。似乎不是很模块化。我的代码附在下面:
<template id="side-navigation">
<nav :class="sidebarcontainer">
<div class="sidebar-left">
<div class="arms-logo">
</div>
<div class="main-menu-items">
<ul>
<li v-for="(item,i) in MainNavLinks"
:key="i"
:class="{'active-main-menu-item': i === activeItem}"
v-on:click="selectItem(i)">
<a>
<i :class="`${item.icon}`"></i>
</a>
</li>
</ul>
</div>
<div class="bottom-menu-items">
<ul>
<li v-for="(item,i) in FeaturesNavLinks"
:key="i"
:class="{ 'active-main-menu-item': i+MainNavLinks.length === activeItem}"
v-on:click="selectItem(i+MainNavLinks.length)">
<a>
<i :class="`${item.icon}`"></i>
</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-right">
</div>
</nav>
</template>
<script>
Vue.component('side-navigation', {
template: '#side-navigation',
methods: {
selectItem(i) {
this.activeItem = i;
},
},
data() {
return {
activeItem: null,
sidebarcontainer: 'sidebar-container',
MainNavLinks: [
{
name: 'Dashboard',
link: '/',
icon: 'fa fa-th-large fa-lg',
SubNavLinks: [
{
Name: 'Dashboard Item 1',
Link: '/DashboardItem1'
},
{
Name: 'Dashboard Item 2',
Link: '/DashboardItem2'
}
]
},
{
name: 'Reviews',
link: '/Reviews',
icon: 'far fa-clipboard fa-lg',
SubNavLinks: [
{
Name: 'Reviews Item 1',
Link: '/ReviewsItem1'
},
{
Name: 'Reviews Item 2',
Link: '/ReviewsItem2'
}
]
},
{
name: 'Upload',
link: '/Upload',
icon: 'fa fa-upload fa-lg',
SubNavLinks: [
{
Name: 'Upload Item 1',
Link: '/UploadItem1'
},
{
Name: 'Upload Item 2',
Link: '/UploadItem2'
}
]
},
{
name: 'Analytics',
link: '/Analytics',
icon: 'fas fa-chart-line fa-lg',
SubNavLinks: [
{
Name: 'Analytics Item 1',
Link: '/AnalyticsItem1'
},
{
Name: 'Analytics Item 2',
Link: '/AnalyticsItem1'
}
]
},
{
name: 'Files',
link: '/Files',
icon: 'far fa-folder-open fa-lg',
SubNavLinks: [
{
Name: 'Files Item 1',
Link: '/FilesItem1'
},
{
Name: 'Upload Item 2',
Link: '/FilesItem1'
}
]
}
],
FeaturesNavLinks: [
{
name: 'Notifications',
link: '/',
icon: 'fas fa-bell fa-lg'
},
{
name: 'Chat',
link: '/',
icon: 'fas fa-comment-alt fa-lg'
},
{
name: 'Email',
link: '/',
icon: 'fas fa-envelope fa-lg'
}
]
}
}
})
</script>
<style scoped>
.sidebar-container {
display: flex;
flex-direction: row;
box-shadow: 2px 0px 4px -1px rgb(0 0 0 / 15%);
position:sticky;
}
.sidebar-left {
display: flex;
flex-direction: column;
align-items: center;
border-right: 1px solid #ebedf3;
width: 100px;
height: 100vh;
position: relative;
}
.sidebar-right {
width: 0px;
position: relative;
}
.active .sidebar-right {
width: 325px;
}
.main-menu-items {
padding: 20px 0px;
flex-grow: 1;
}
.sidebar-container ul {
padding: 0px;
}
.sidebar-container li {
list-style-type: none;
text-align: center;
margin-bottom: 15px;
}
.sidebar-container a {
height: 50px;
width: 50px;
display: flex;
justify-content: center;
align-items: center;
text-decoration: none;
border-radius: .42rem;
}
.sidebar-container a:hover > *, .sidebar-container a:hover {
background-color: #f2f5f8;
color: #ff7d44 !important;
}
.sidebar-container i {
color: #a5a5a5;
}
.active-main-menu-item a > *, .active-main-menu-item a {
background-color: #f2f5f8;
color: #ff7d44 !important;
}
</style>