Laravel跳转单篇文章子路由时导航栏菜单active状态失效问题
实现方案
问题根因
原有set_active辅助函数仅支持路径完全相等匹配:访问单篇文章详情页时,Request::path()返回的路径为posts/quia-laboriosam-nam-nostrum-porro,和传入的匹配值posts不相等,因此不会返回激活样式类。
具体修改
1. 升级辅助函数,增加前缀匹配逻辑
替换原有set_active函数代码为以下版本,同时支持完全匹配、前缀匹配两种规则:
use Illuminate\Support\Str; function set_active($route) { $currentPath = Request::path(); if (is_array($route)) { foreach ($route as $path) { // 完全匹配当前路径,或是当前路径的子路径,均判定为激活 if ($currentPath === $path || Str::startsWith($currentPath, $path . '/')) { return 'active-menu'; } } return ''; } return $currentPath == $route || Str::startsWith($currentPath, $route . '/') ? 'active-menu' : ''; }
兼容提示:如果运行环境为PHP8.0及以上版本,可以直接使用PHP原生的
str_starts_with()函数替换Str::startsWith(),无需导入Illuminate\Support\Str类。
2. 导航栏代码无需调整
原有导航栏的调用逻辑保持原样即可,不需要做任何修改:
<li class="{{ set_active('posts') }}"> <a href="{{ url('/posts')}}">Blog</a> </li>
生效效果
修改完成后,两类场景下Blog菜单都会自动保持激活状态:
- 访问文章列表页
/posts:命中完全匹配规则 - 访问所有
/posts前缀的子页面(包括文章详情、文章分类筛选、文章标签页、文章搜索结果页等):命中前缀匹配规则
后续其他导航项如果需要实现同效果,直接传入对应路由前缀即可,例如set_active('admin')会自动让所有/admin开头的后台页面对应菜单保持激活。
内容的提问来源于stack exchange,提问作者DapOne
相关产品推荐
相关产品推荐

