Laravel 5.5:如何自动为每个页面调用函数生成动态导航?
自动为所有页面生成左侧导航菜单的方案
针对你不想在每个控制器重复编写左侧菜单生成代码的需求,这里有几个Laravel生态里常用的自动化实现方案,你可以根据项目场景选择最适合的:
方案一:视图Composer(推荐用于局部视图场景)
视图Composer是Laravel专门用来给指定视图绑定数据的工具,完美适配你的leftnav.blade.php局部视图需求——只有当这个视图被渲染时,才会自动执行数据生成逻辑,性能更高效。
实现步骤:
- 创建视图Composer类
在app/View/Composers目录下新建LeftNavComposer.php(如果目录不存在就手动创建),把菜单生成逻辑移到这里:
namespace App\View\Composers; use Illuminate\View\View; // 替换成你实际使用的模型或逻辑类 use App\Models\Menu; class LeftNavComposer { /** * 给视图绑定菜单数据 */ public function compose(View $view) { // 调用你的菜单生成方法,这里也可以直接调用Helper函数 $tree = $this->generateSiteTree(0); $view->with('tree', $tree); } /** * 菜单生成逻辑(可以直接复用你已有的代码) */ private function generateSiteTree($parentId) { // 这里写你的菜单树生成逻辑,比如从数据库查询并构建层级结构 return Menu::where('parent_id', $parentId)->orderBy('sort')->get(); } }
- 注册视图Composer
打开app/Providers/AppServiceProvider.php,在boot方法里注册这个Composer,指定绑定到你的leftnav视图:
namespace App\Providers; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; use App\View\Composers\LeftNavComposer; class AppServiceProvider extends ServiceProvider { public function boot() { // 绑定到leftnav局部视图,如果视图在子目录比如layouts.leftnav,就写对应路径 View::composer('leftnav', LeftNavComposer::class); } }
这样以后只要leftnav.blade.php被渲染,就会自动获取到$tree数据,完全不用在控制器里手动传递了。
方案二:全局中间件
如果你的所有页面都需要这个菜单数据,也可以用全局中间件来实现——每个请求都会自动执行菜单生成逻辑,并把数据共享给所有视图。
实现步骤:
- 创建中间件
运行Artisan命令生成中间件:
php artisan make:middleware ShareLeftNavData
- 编写中间件逻辑
打开app/Http/Middleware/ShareLeftNavData.php,添加菜单生成和数据共享的代码:
namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use App\Models\Menu; class ShareLeftNavData { public function handle(Request $request, Closure $next) { // 生成菜单数据 $tree = $this->generateSiteTree(0); // 把数据共享给所有视图 view()->share('tree', $tree); return $next($request); } private function generateSiteTree($parentId) { // 复用你的菜单生成逻辑 return Menu::where('parent_id', $parentId)->orderBy('sort')->get(); } }
- 注册全局中间件
打开app/Http/Kernel.php,把这个中间件添加到$middleware数组里:
protected $middleware = [ // ...其他已有的全局中间件 \App\Http\Middleware\ShareLeftNavData::class, ];
方案三:基础控制器继承
如果你的所有业务控制器都继承自同一个基础控制器,也可以把菜单生成逻辑放到基础控制器的构造方法里,这样每个控制器初始化时都会自动共享菜单数据。
实现步骤:
打开app/Http/Controllers/Controller.php(这是Laravel默认的基础控制器),在构造方法里添加代码:
namespace App\Http\Controllers; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; use App\Models\Menu; class Controller extends BaseController { use AuthorizesRequests, DispatchesJobs, ValidatesRequests; public function __construct() { // 生成并共享菜单数据 $tree = $this->generateSiteTree(0); view()->share('tree', $tree); } private function generateSiteTree($parentId) { // 复用你的菜单生成逻辑 return Menu::where('parent_id', $parentId)->orderBy('sort')->get(); } }
之后你的所有业务控制器只要继承这个基础控制器,就会自动拿到菜单数据了。
内容的提问来源于stack exchange,提问作者Niladri Banerjee - Uttarpara
相关产品推荐
相关产品推荐

