从 VueJS 中的路由器链接突出显示父菜单

时间:2021-04-05 13:24:31

标签: vue.js vuejs2 vue-component vue-router

我开发了一个拆分侧边栏菜单。左侧有图标,按下后会激活右侧子菜单项的菜单栏。子菜单包含路由器链接标签,我可以点击所选链接的活动类来突出显示它。问题是我还需要将活动类应用于左侧图标栏,因为那是父菜单。单击图标加载应用程序后,如果选择了该项目,则活动类将变为活动状态。我的问题纯粹是在加载期间,因为如果有人输入 URL 自定义路由器链接,左侧边栏没有任何将其链接到路由器的功能,因为链接位于侧边栏的右侧。 vue 中内置的任何方法来处理这样的事情?如果没有,我可以尝试另一种方法吗?

我的侧边栏组件代码如下。代码基本上创建了两个面,图标面和菜单面。图标和菜单是使用 v-for 开发的,并循环访问提供链接和图标的数据集。

<template id="side-navigation">
    <div :class="theme">
        <nav :class="sidebarcontainer">
            <div class="sidebar-left">
                <div class="arms-icon">
                </div>
                <div class="main-menu-items">
                    <ul>
                        <li v-for="(item,i) in MainNavLinks"
                            :key="i"
                            :class="{'active-main-menu-item': i === activeIconIndex}"
                            v-on:click="selectIconItem(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 === activeIconIndex}"
                            v-on:click="selectIconItem(i+MainNavLinks.length)">
                            <a>
                                <i :class="item.icon"></i>
                            </a>
                        </li>
                    </ul>
                </div>
            </div>
            <div class="sidebar-right" :class="{'active-right-sidebar' : isIconActive}">
                <div class="sidebar-content">
                    <div class="searchbarcontent">
                        <div class="inputWithIcon">
                            <input placeholder="Search" id="sub-nav-seachbar" class="searchbar" type="text">
                            <i class="fas fa-search" id="searchicon-btn"></i>
                        </div>
                    </div>
                    <div v-for="(item,i) in MainNavLinks"
                         :key="i"
                         :class="{'active-sub-menu-item' : i === activeIconIndex}"
                         class="right-menu-content">
                        <ul>
                            <li v-for="(SubNavLink,i) in item.SubNavLinks"
                                class="sub-nav-group">
                                <h4 class="sub-nav-header">
                                    {{SubNavLink.SubNavHeader}}
                                </h4>
                                <ul>
                                    <li v-for="(SubNavMenuItem,i) in SubNavLink.SubNavMenuItems"
                                        class="sub-nav-items">
                                        <router-link :to="SubNavMenuItem.link"><span class="sub-menu-icons"><i :class="SubNavMenuItem.icon"></i></span>{{SubNavMenuItem.title}}</router-link>
                                    </li>
                                </ul>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </nav>

    </div>
</template>
<script>
    Vue.component('side-navigation', {
        template: '#side-navigation',
        methods: {
            selectIconItem(i) {
                if (this.activeIconIndex === i) {
                    if (this.isIconActive === true) {
                        this.isIconActive = false;
                    } else {
                        this.isIconActive = true;
                    }
                } else {
                    this.activeIconIndex = i;
                    this.isIconActive = true;
                }
            },
        },

        data() {
            return {
                theme: 'color',
                activeIconIndex: null,
                isIconActive: false,
                sidebarcontainer: 'sidebar-container',
                MainNavLinks: [
                    {
                        name: 'Dashboard',
                        link: '/',
                        icon: 'fa fa-th-large fa-lg',
                        SubNavLinks: [
                            {
                                SubNavHeader: 'Dash Category 1',
                                SubNavMenuItems: [{
                                    title: 'Item 1',
                                    link: '/',
                                    icon: 'fas fa-list-ul'
                                },
                                {
                                    title: 'Item 2',
                                    link: '/item2',
                                    icon: 'fas fa-list-ul'
                                }]
                            },
                            {
                                SubNavHeader: 'Dash Category 2',
                                SubNavMenuItems: [{
                                    title: 'Item 3',
                                    link: '/item3',
                                    icon: 'fas fa-list-ul'
                                },
                                {
                                    title: 'Item 4',
                                    link: '/item4',
                                    icon: 'fas fa-list-ul'
                                }]
                            }
                        ]
                    },
                    {
                        name: 'Reviews',
                        link: '/Reviews',
                        icon: 'far fa-clipboard fa-lg',
                        SubNavLinks: [
                            {
                                SubNavHeader: 'Reviews Category 1',
                                SubNavMenuItems: [{
                                    title: 'Item 1',
                                    link: '/item1',
                                    icon: 'fas fa-list-ul'
                                },
                                {
                                    title: 'Item 2',
                                    link: '/item2',
                                    icon: 'fas fa-list-ul'
                                }]
                            },
                            {
                                SubNavHeader: 'Reviews Category 2',
                                SubNavMenuItems: [{
                                    title: 'Item 3',
                                    link: '/item3',
                                    icon: 'fas fa-list-ul'
                                },
                                {
                                    title: 'Item 4',
                                    link: '/item4',
                                    icon: 'fas fa-list-ul'
                                }]
                            }
                        ]
                    },
                    {
                        name: 'Upload',
                        link: '/Upload',
                        icon: 'fa fa-upload fa-lg',
                        SubNavLinks: [
                        ]
                    },
                    {
                        name: 'Analytics',
                        link: '/Analytics',
                        icon: 'fas fa-chart-line fa-lg',
                        SubNavLinks: [
                        ]
                    },
                    {
                        name: 'Files',
                        link: '/Files',
                        icon: 'far fa-folder-open fa-lg',
                        SubNavLinks: [
                        ]
                    }
                ],
                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'
                    },
                    {
                        name: 'Profile',
                        link: '/',
                        icon: 'fas fa-user 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;
    }

/*left icon section of sidebar*/
    .sidebar-left {
        display: flex;
        flex-direction: column;
        align-items: center;
        width: 100px;
        position: relative;
        height: 100vh;
        overflow-y: auto;
        overflow-x: hidden;
    }

    .color .sidebar-left {
        background-color: #ff7100;
    }

    .light .sidebar-left {
        border-right: 1px solid #ebedf3;
    }

    .main-menu-items {
        padding: 20px 20px;
        flex-grow: 1;
    }
    .sidebar-left ul {
        padding: 0px;
    }
    .sidebar-left li {
        list-style-type: none;
        text-align: center;
        margin-bottom: 10px;
    }
    .sidebar-left a {
        height: 50px;
        width: 50px;
        display: flex;
        justify-content: center;
        align-items: center;
        text-decoration: none;
        border-radius: .42rem;
    }
    .color .sidebar-left a:hover > *, .color .sidebar-left a:hover {
        background-color: #da6000f7;
        color: #fff !important;
    }

    .light .sidebar-left a:hover > *, .light .sidebar-left a:hover {
        background-color: #f3f6f9;
        color: #ff7d44 !important;
    }

    .color .active-main-menu-item a > *, .color .active-main-menu-item a {
        background-color: #da6000f7;
        color: #fff !important;
    }

    .light .active-main-menu-item a > *, .light .active-main-menu-item a {
        background-color: #f3f6f9;
        color: #ff7d44 !important;
    } 

    .color .sidebar-left i {
        color: #fff;
    }

    .light .sidebar-left i {
        color: #a5a5a5;
    }
   
    /*right sidebar styling*/

    .sidebar-right {
        width: 0px;
        position: relative;
        transition: all 1s;
        overflow: hidden;
        height: 100vh;
        overflow-y: auto;
    }
    .active-right-sidebar {
        width: 325px;
        transition: all 1s;
    }
    .sidebar-content{
        padding:20px;
    }
    .right-menu-content {
        display: none;
        overflow: hidden;
        white-space: nowrap;
        padding: 0px 20px;
    }
    .active-sub-menu-item {
        display: block;
    }
    /*sidebar searchbar*/
    .searchbar {
        width: 100%;
        height: 40px;
        border: 0px;
        border-radius: 40px;
        outline: none;
        padding: 8px;
        box-sizing: border-box;
        transition: 0.3s;
        letter-spacing: 2px;
        background-color: #e6e6e6;
    }


    .inputWithIcon input[type="text"], .inputWithIcon input[type="password"] {
        padding-left: 35px;
    }

    .inputWithIcon {
        position: relative;
        height: 40px;
        overflow: hidden;
        width: 100%;
    }

    .searchbarcontent {
        padding: 0px 20px;
        display: flex;
        height: 50px;
        width: 100%;
        justify-content: center;
        align-items: center;
        margin-bottom: 10px;
    }

    #searchicon-btn {
        padding: 9px 25px 9px 5px;
        top: 4px;
        color: #aaa;
        position: absolute;
        right: 0px;
        cursor: pointer;
    }

    .sidebar-right ul {
        padding: 0px;
    }

    .sidebar-right li {
        list-style-type: none;
    }

    .sidebar-right a {
        text-decoration: none;
    }

    .sub-nav-header {
        display: flex;
        align-items: center;
        height: 50px;
        font-size: 1rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: .3px;
        color: #7e8299;
    }

    .sub-nav-items {
        display: flex;
        align-items: center;
        height: 45px;
        font-size: .9rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .3px;
    }

    .sub-nav-items a {
        color: #7f818d;
    }

    .sub-nav-group{
        margin-bottom: 15px;
    }
    .sub-menu-icons {
        width: 30px;
        padding-right: 20px;
    }

    .router-link-exact-active {
        color: #ff7100 !important;
    }

    /*scrollbar*/
    /* custom scrollbar */
    ::-webkit-scrollbar {
        width: 20px;
    }

    ::-webkit-scrollbar-track {
        background-color: transparent;
    }

    ::-webkit-scrollbar-thumb {
        background-color: #00000014;
        border-radius: 20px;
        border: 6px solid transparent;
        background-clip: content-box;
    }

    ::-webkit-scrollbar-thumb:hover {
        background-color: #0000001f;
    }

</style>

1 个答案:

答案 0 :(得分:0)

使用nested routes

<router-link> 的类应该是 .router-link-active

确切的 <router-link> 应该有 .router-link-exact-active

查看 this code 以获取交互式示例。