Выделение родительского меню из ссылки на маршрутизатор в VueJS

Я разработал разделенное меню боковой панели. Слева есть значки, при нажатии на которые активируется строка меню с правой стороны для элементов подменю. Подменю содержит теги маршрутизатора-ссылки, которые я могу использовать в активном классе выбранной ссылки, чтобы выделить его. Проблема в том, что мне нужно применить активный класс к левой панели значков, поскольку это родительское меню. После загрузки приложения при нажатии значков активный класс станет активным, если элемент выбран. Моя проблема возникает исключительно во время загрузки, потому что если кто-то вводит 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>
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
23
1

Ответы 1

Используйте вложенные маршруты.

Родительские <router-link> должны иметь класс .router-link-active.

Точный <router-link> должен иметь .router-link-exact-active.

Ознакомьтесь с интерактивным примером этот код.

Я просматриваю этот пример, но изо всех сил пытаюсь понять, как дополнительные ссылки маршрутизатора, привязанные к конкретной ссылке, не отображаются в URL-адресе, как если бы по ним щелкали. По сути, родительское меню не должно влиять на историю или URL-адрес выше, если не щелкнуть элемент в подменю. Имеет ли это смысл?

Bradyboyy88 06.04.2021 03:34

Я протестировал методы в этой ссылке, но все они, похоже, влияют на URL-адрес, и, как отмечалось выше, я не думаю, что патентное меню действительно должно действовать как сама ссылка, верно? Из всех панелей мониторинга, которые я видел, как это разделенное меню, левое меню не действует как ссылка. Остановился на том, как решить эту проблему с помощью vuejs.

Bradyboyy88 06.04.2021 05:43

Другие вопросы по теме