使用场景

如自定义的 header 中需要做 SEO 相关的标题,关键词、描述,导航内容,底栏 footer 公司信息、联系方式等。

这些信息内容因为属于公共部分,被拆分成 header、footer 等公共模板,如果不需要修改还好,如果想要在后台定义修改,则需要对这些公共模板携带对应数据。

使用方法

因为数据只传递一次在所有页面都可用,所以,只要在调用 view 页面模版时带入数据,即可直接使用。

当然可以直接添加一个新的 with 带入公共变量。但这需要每个页面调用 view 渲染时都要加上对应数据。

之前遇到过一个解决方法,就是自定义一个新的 view 方法,内部查询公共变量或者公共数据,然后 compact 传入的数据,再调用框架的 view 方法。

也有说通过 ajax 获取数据的,但这个明显与模板的使用无关。

最好的方法是使用类似中间件或者全局设置里,添加一个 hook 或事件触发来处理这样的需求。百度了一会儿,确实找到了这样的方法

App\Providers\AppServiceProvider 中的 boot 启动方法中添加处理方法:

view()->composer(
    '*',     //模板名多个可用数组"['blade1', 'blade2']"
    'App\Home\Controllers\BaseController@HomeInitData'    //方法名或者类中的方法
);

这里的 view() 是助手方法,也可以用 View::composer,这里的 View 引入路径 use Illuminate\Support\Facades\View;

composer 第一个参数可以为 *、数组,也可以是单个模板名(字符串)。注意如果有模板存放在二级目录下,需要加上目录名。比如:includes/header

composer 第二个参数为 View 的处理方法,可以如上写成类方法,按照 Laravel 9.x 文档,也可以如下:

// 使用基于类的生成器...
View::composer('profile', ProfileComposer::class);

// 使用基于闭包的生成器...
View::composer('dashboard', function ($view) {
    //
});
使用基于类的生成器,每次渲染 profile 视图时都会执行 App\View\Composers\ProfileComposer 类的 compose 方法。

自定义的处理方法:

use Illuminate\View\View;

...

public function HomeInitData(View $view)
{
    $menuTree = $this->menuTree();
    $setting = $this->getSetting();
    $data = [
        'navs' => !empty($menuTree) ? $menuTree : [],
        'setting' => !empty($setting) ? $setting : [],
        'seo' => [
            'title' => !empty($setting['seo_title']) ? $setting['seo_title'] : getenv('APP_NAME'),
            'keywords' => !empty($setting['seo_keywords']) ? $setting['seo_keywords'] : getenv('APP_NAME'),
            'description' => !empty($setting['seo_description']) ? $setting['seo_description'] : getenv('APP_NAME'),
        ],
        'links' => $this->getFlink()
    ];
    //dd($data);
    $view->with('common',$data);//传递变量
}

视图中使用:

# 引入 header 视图
@include('includes/header');

# header 视图中使用
{{$common['link']}}
文章目录