You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中获取当前路由Slug及实现侧边栏菜单请求时自动展开并高亮

Hey there! Let's fix up your Laravel sidebar menu so it automatically expands and highlights the active item based on the current route's slug. I'll walk you through refactoring your code to make it dynamic and reusable, no more hardcoded paths!

First: How to Get the Current Route's Slug

There are a couple of reliable ways to grab the slug from your current route:

  • If your route defines a {slug} parameter (like Route::get('backend/{slug}', ...)), use Route::current()->parameter('slug') to get the direct slug value.
  • For nested routes (e.g., backend/parent-slug/child-slug), you can get all parameters with Route::current()->parameters() and check against your menu's slug values.
  • Alternatively, use request()->segment(2) (for the second segment in backend/{slug}) or request()->segment(3) for nested slugs.

Refactored Sidebar Menu Code

The main issues with your current code are hardcoded active checks and variable overwriting in loops. Let's rewrite it with recursion (for nested menus) and dynamic checks:

First, create a reusable Blade partial for submenus (e.g., resources/views/partials/sidebar-submenu.blade.php):

<li class="nav-item has-treeview {{ request()->is('backend/' . $menu->slug . '*') ? 'menu-open' : '' }}">
    <a href="{{ url('backend/' . $menu->slug) }}" 
       class="nav-link {{ request()->is('backend/' . $menu->slug) || request()->is('backend/' . $menu->slug . '/*') ? 'active' : '' }}">
        {{ $menu->name }}
        @if(count($menu->children) > 0)
            <i class="fas fa-angle-left right"></i>
        @endif
    </a>

    {{-- Render child menus recursively --}}
    @if(count($menu->children) > 0)
        <ul class="nav nav-treeview {{ request()->is('backend/' . $menu->slug . '*') ? 'show' : '' }} dropdown" aria-labelledby="dropdownBtn">
            @foreach($menu->children as $childMenu)
                @include('partials.sidebar-submenu', ['menu' => $childMenu])
            @endforeach
        </ul>
    @endif
</li>

Then update your main sidebar code to use this partial:

{{-- Top-level menu items --}}
<li class="nav-item has-treeview {{ request()->is('backend/' . $menu->slug . '*') ? 'menu-open' : '' }}">
    <a href="#" 
       class="nav-link {{ request()->is('backend/' . $menu->slug) || request()->is('backend/' . $menu->slug . '/*') ? 'active' : '' }}">
        {{ $menu->name }}
        @if(count($menu->children) > 0)
            <i class="fas fa-angle-left right"></i>
        @endif
    </a>

    {{-- Load submenus using the partial --}}
    @if(count($menu->children) > 0)
        <ul class="nav nav-treeview {{ $menu->parent_id === 0 ? 'dropdown' : '' }}">
            @foreach($menu->children as $childMenu)
                @include('partials.sidebar-submenu', ['menu' => $childMenu])
            @endforeach
        </ul>
    @endif
</li>

What Changed & Why

  1. Dynamic Active/Open Checks:

    • request()->is('backend/' . $menu->slug . '*'): This checks if the current route starts with the menu's slug path (works for both the menu's direct page and its nested subpages).
    • The active class is added if the route is exactly the menu's URL or any subroute under it.
  2. Recursive Rendering:

    • By moving submenu logic into a partial, we can handle infinite levels of nested menus without repeating code.
    • We renamed the loop variable to $childMenu to avoid overwriting the parent $menu variable (a common bug in nested loops!).
  3. Cleaner Conditional Classes:

    • Removed hardcoded checks like request()->is('backend/library-setting*') — now every menu uses its own slug for checks.

Bonus: Using Route Names (Even More Reliable)

If you've named your routes (e.g., Route::get('backend/{slug}', [MenuController::class, 'show'])->name('backend.menu')), you can use route names instead of URL paths for more stable checks:

{{-- For active class --}}
class="nav-link {{ request()->routeIs('backend.' . $menu->route_name . '*') ? 'active' : '' }}"

{{-- For menu-open class --}}
class="nav-item has-treeview {{ request()->routeIs('backend.' . $menu->route_name . '*') ? 'menu-open' : '' }}"

Just make sure your menu model has a route_name field that matches your route names.

That should do it! Your sidebar will now automatically expand and highlight the correct menu item based on the current route's slug.

内容的提问来源于stack exchange,提问作者Munindra kanxa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 18:17:52