视图

创建视图

查找有关编写 Blade 模板的更多信息?请查看完整的 Blade 文档

视图包含了应用提供的 HTML,并将控制器/应用逻辑和视图显示逻辑分开。视图存储在 resources/views 目录中。一个简单的视图可能看起来像这样:

resources/views/greeting.blade.php

<html>
    <body>
        <h1>Hello, {{ $name }}</h1>
    </body>
</html>

由于该视图存储在 resources/views/greeting.blade.php,因此我们可以像这样使用全局辅助函数 view 返回它:

Route::get('/', function () {
    return view('greeting', ['name' => 'James']);
});

如您所见,传递给 view 辅助函数的第一个参数对应于 resources/views 目录中视图文件的名字。第二个参数是视图要使用的数据数组。在本示例中,我们传递 name 变量,可以使用 Blade 语法 将此变量显示到视图中。

当然,视图也可以在 resources/views 目录的子目录中进行嵌套。然后用「点」语法来引用嵌套的视图。例如,如果视图存储在 resources/views/admin/profile.blade.php,可以像这样引用它:

return view('admin.profile', $data);

判断视图是否存在

如果要判断一个视图是否存在,可以使用 View Facade。如果视图存在,exists 方法将返回 true

use Illuminate\Support\Facades\View;

if (View::exists('emails.customer')) {
    //
}

创建首个可用视图

使用 first 方法,可以创建存在于给定视图数组中的首个视图。如果应用或扩展包允许自定义或重写视图,会非常有用:

return view()->first(['custom.admin', 'admin'], $data);

当然,也可以通过 View Facade 调用此方法:

use Illuminate\Support\Facades\View;

return View::first(['custom.admin', 'admin'], $data);

向视图传递数据

正如您在前面的示例中看到的那样,可以将一个数据数组传递给视图:

return view('greetings', ['name' => 'Victoria']);

以这种方式传递数据时,数据应该是一个键/值对数组。在视图中,可以使用相应的键来获取每个值,例如 <?php echo $key; ?>。作为传递一个完整的数据数组给视图的辅助函数 view 的替代方法,可以使用 with 方法将部分数据添加到视图:

return view('greeting')->with('name', 'Victoria');

所有视图共享数据

有时,可能在应用渲染所有视图时需要共享一些数据。可以使用视图 Facade 的 share 方法来执行此操作。通常来说,应该在服务提供者的 boot 方法中调用 share 方法。您可以自由地将它们添加到 AppServiceProvider 或生成一个单独的服务提供者:

namespace App\Providers;

use Illuminate\Support\Facades\View;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 启动任何应用服务
     *
     * @return void
     */
    public function boot()
    {
        View::share('key', 'value');
    }

    /**
     * 注册服务提供者
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

视图合成器

视图合成器是渲染视图时调用的回调或者类方法。如果每次渲染视图的时候都希望将数据绑定到视图,视图合成器可以帮助您将该逻辑组织到一个单独的位置。

我们将演示在一个 服务提供者 中注册视图合成器。我们会使用 View Facade 获取底层 Illuminate\Contracts\View\Factory Contract 的实现。要记住,Laravel 不包含视图合成器的默认目录。您可以随意组织它们。例如,可以创建一个 app/Http/ViewComposers 目录:

namespace App\Providers;

use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider
{
    /**
     * 注册容器绑定
     *
     * @return void
     */
    public function boot()
    {
        // 使用基于类的视图合成器
        View::composer(
            'profile', 'App\Http\ViewComposers\ProfileComposer'
        );

        // 使用基于闭包的视图合成器
        View::composer('dashboard', function ($view) {
            //
        });
    }

    /**
     * 注册服务提供者
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

要记住,如果您创建了一个新的服务提供者用于注册视图合成器,需要将其添加到 config/app.php 配置文件的 providers 数组中。

现在我们已经注册了视图合成器,每次渲染 profile 视图时,都会执行 ProfileComposer@compose 方法。接着,我们来定义视图合成器类:

namespace App\Http\ViewComposers;

use Illuminate\View\View;
use App\Repositories\UserRepository;

class ProfileComposer
{
    /**
     * 用户库的实现
     *
     * @var UserRepository
     */
    protected $users;

    /**
     * 创建一个新的配置视图合成器
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        // 服务容器会自动解析依赖
        $this->users = $users;
    }

    /**
     * 将数据绑定到视图
     *
     * @param  View  $view
     * @return void
     */
    public function compose(View $view)
    {
        $view->with('count', $this->users->count());
    }
}

在渲染视图前,Illuminate\View\View 的实例会调用视图合成器的 compose 方法。可以使用 with 方法将数据绑定到视图。

由于所有视图合成器都是通过 服务容器 解析的,因此可以在视图合成器的构造函数中对任何依赖使用类型提示。

将视图合成器添加到多个视图

可以将视图数组作为 composer 方法的第一个参数传递,将视图合成器一次添加到多个视图:

View::composer(
    ['profile', 'dashboard'],
    'App\Http\ViewComposers\MyViewComposer'
);

composer 方法也接收 * 作为通配符,将视图合成器添加到所有视图:

View::composer('*', function ($view) {
    //
});

视图构造器

视图 构造器 和视图合成器非常类似;但是,它们在视图实例化后就立即执行了,而不是等到视图即将渲染时。要注册一个视图构造器,使用 creator 方法:

View::creator('profile', 'App\Http\ViewCreators\ProfileCreator');