【问题标题】:Using 2 different blade root template for Vue, with Laravel 8 and Inertia?为 Vue 使用 2 个不同的刀片根模板,以及 Laravel 8 和 Inertia?
【发布时间】:2021-06-15 04:25:18
【问题描述】:

所以我正在使用 Inertia 和 Vue 开发 Laravel 8 应用程序。

想法是大部分页面都是 Laravel + Blade (有利于 SEO、快速加载等...),但是对于需要大量用户交互的选定页面,我在 Blade 模板中插入了一个 Vue 组件,其中互动需要发生。

使用 Inertia,这是通过在 Laravel 路由调用的 Controller 中使用 return Inertia::render('vueComponent') 调用 Vue 组件来完成的。数据可以传递给 Vue 实例,甚至可以传递给 Blade 模板,所以这很好(见下文)。

namespace App\Http\Controllers;
use Inertia\Inertia;

class RangePageController extends Controller
{
    public function show(string $lang='fr')
    {
        // Strip the trailing slash from $lang
        $lang = Str::before($lang, '/');

        return Inertia::render('ProductsGallery', ['bar' => "Hello World"])->withViewData(['lang' => $lang]);
    }
}

默认情况下,文件“/resources/views/app.blade.php”是用Vue组件渲染的,替换了@inertia指令(加上一些Vue数据)。整洁。

默认情况下,使用刀片布局文件“app.blade.php”。文档指定可以更改默认值:Inertia\Inertia::setRootView('name');

问题:除了更改默认值,有没有办法在从Controller调用不同页面时选择不同的Blade布局文件(并像上面一样注入Vue组件)?例如,我想为我的电子商务购物篮使用一种 Blade 布局,而为我的管理页面使用另一种布局。就像为一个页面选择“app1.blade.php”,为另一个页面选择“app2.blade.php”。

非常感谢! E.

【问题讨论】:

    标签: laravel vue.js laravel-blade inertiajs


    【解决方案1】:

    找到了解决方案,物有所值。

    1. 我创建了 2 个新的 /Http/Middleware,扩展了“HandleInertiaRequest.php” 中间件。
    2. 在每个扩展类中,我将“受保护的 $rootView”设置为指向 /resources/views 中的自定义刀片布局文件。例如 protected $rootView = 'admin.app';,指向 /resources/views/admin/app.blade.php,“网络”也是如此 app.blade.php.
    3. 然后我在 Kernel.php 复制“web”组中的列表,我替换 默认的“\App\Http\Middleware\HandleInertiaWebRequests::class” 与扩展类(在“web”和“admin”组中)对齐。
    4. 我在“routes”文件夹中创建了一个“admin”路由文件来托管 将使用“管理员”布局的路线。中的路线 默认的“web”路由文件将使用位于“resources/views/web/”中的 Blade 布局。

    可能有一些更好的解决方案,但这个似乎可行。

    注意:我在 GitHub 上看到过类似的讨论,但除了有 2 个不同的 Vue 实例:一个用于“web”,一个用于“admin”。不知道这会带来什么,但我仍在寻找一种方法来做到这一点!如果有人有想法...

    【讨论】:

      【解决方案2】:

      稍微更新一下您的 HandleInertiaRequests

      public function version(Request $request)
          {
              // Add the root view tho the version hash.
              // This forces inertia to make a hard reload when the template changes.
              return $this->rootView . parent::version($request);
          }
      
      public function handle(Request $request, \Closure $next, $rootView = null)
          {
              if ($rootView) {
                  $this->rootView = $rootView;
              }
      
              return parent::handle($request, $next);
          }
      

      同时从全局中间件中移除 HandleInertiaRequests 并将其添加为命名中间件

          protected $routeMiddleware = [
               ...
              'inertia' => \App\Http\Middleware\HandleInertiaRequests::class,
          ];
      

      现在您可以根据需要填充路线、路线组

      Route::group(['middleware' => ['Admin:Client.Dashboard.app']], function () {
          Route::get('/admin/dashboard', [
              'as'   => 'admin.dashboard',
              'uses' => 'Admin\DashboardController@index',
          ]);
      });
      Route::middleware('inertia:app')
          ->group(base_path('routes/auth.php'));
      

      【讨论】:

        【解决方案3】:

        您可以使用属性和方法更改中间件(HandleInertiaRequest.php)中的interia的根模板

        // Set root template via property
        protected $rootView = 'app';
        
        // OR
        // Set root template via method
        public function rootView(Request $request)
        {
            return 'app';
        }
        

        现在在 rootView() 方法中过滤请求,并根据您的需要更改根模板,只需使用简单的 if-else 条件。

        【讨论】:

          猜你喜欢
          • 2016-08-20
          • 2020-06-22
          • 2019-12-02
          • 2020-06-24
          • 1970-01-01
          • 2021-03-30
          • 2013-04-29
          • 2019-11-07
          相关资源
          最近更新 更多