Skip to content

页面

Livewire 组件可以通过直接分配给路由来用作完整的页面。这允许你使用 Livewire 组件构建完整的应用程序页面,并具有额外的功能,如自定义布局、页面标题和路由参数。

路由到组件

要路由到组件,请在 routes/web.php 文件中使用 Route::livewire() 方法:

php
Route::livewire('/posts/create', 'pages::post.create');

当你访问指定的 URL 时,组件将使用应用程序的布局渲染为一个完整的页面。

组件命名空间

你可能注意到上面路由示例中的 pages:: 前缀。Livewire 自动注册几个组件命名空间以便更好地组织:

  • pages:: — 指向 resources/views/pages/
  • layouts:: — 指向 resources/views/layouts/

这些命名空间为 Livewire 组件和 Blade 组件注册,允许你将应用程序的页面和布局组织在专用目录中。例如:

php
// 这些都自动工作:
Route::livewire('/dashboard', 'pages::dashboard');
Route::livewire('/profile', 'pages::user.profile');

// 在 Blade 模板中:
<livewire:pages::dashboard />
<x-layouts::app />

你可以在 config/livewire.php 文件中自定义这些命名空间或添加你自己的:

php
'component_namespaces' => [
    'layouts' => resource_path('views/layouts'),
    'pages' => resource_path('views/pages'),
    'admin' => resource_path('views/admin'),  // 添加自定义命名空间
],

布局

通过路由渲染的组件将使用应用程序的布局文件。默认情况下,Livewire 查找名为 layouts::app 的布局,位于 resources/views/layouts/app.blade.php

如果该文件不存在,你可以通过运行以下命令创建它:

shell
php artisan livewire:layout

此命令将生成一个名为 resources/views/layouts/app.blade.php 的文件。

确保你在此位置创建了一个 Blade 文件并包含了 占位符:

blade
<!-- resources/views/layouts/app.blade.php -->

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <title>{{ $title ?? 'Page Title' }}</title>

        @livewireStyles
    </head>
    <body>
        {{ $slot }}

        @livewireScripts
    </body>
</html>

你可以通过更新 config/livewire.php 文件中的 component_layout 配置选项来自定义默认布局:

php
'component_layout' => 'layouts::dashboard',

组件特定布局

要为特定组件使用不同的布局,你可以将 #[Layout] 属性放置在组件类上方:

php
<?php

use Livewire\Attributes\Layout;
use Livewire\Component;

new
#[Layout('layouts::dashboard')] // [tl! highlight]
class extends Component
{
	// ...
};

或者,你可以在组件的 render() 方法中使用 ->layout() 方法:

php
<?php

use Livewire\Component;

new class extends Component
{
	// ...

    public function render()
    {
        return $this->view()
            ->layout('layouts::dashboard'); // [tl! highlight]
    }
};

设置页面标题

为应用程序中的每个页面分配唯一的页面标题对用户和搜索引擎都很有帮助。

要为页面组件设置自定义页面标题,首先确保你的布局文件包含动态标题:

blade
<head>
    <title>{{ $title ?? 'Page Title' }}</title>
</head>

接下来,在 Livewire 组件的类上方添加 #[Title] 属性并传递你的页面标题:

php
<?php

use Livewire\Attributes\Title;
use Livewire\Component;

new
#[Title('Create post')] // [tl! highlight]
class extends Component
{
	// ...
};

这将为组件设置页面标题。在此示例中,当渲染组件时,页面标题将为"创建文章"。

如果你需要传递动态标题,例如使用组件属性的标题,你可以在组件的 render() 方法中使用 ->title() 流式方法:

php
public function render()
{
    return $this->view()
	     ->title('Create Post'); // [tl! highlight]
}

设置额外的布局文件插槽

如果你的布局文件除了 $slot 之外还有任何命名插槽,你可以通过在根元素外部定义 <x-slot> 来设置它们在 Blade 视图中的内容。例如,如果你想能够为每个组件单独设置页面语言,可以在布局文件的开始 HTML 标签中添加动态 $lang 插槽:

blade
<!-- resources/views/layouts/app.blade.php -->

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', $lang ?? app()->getLocale()) }}"> <!-- [tl! highlight] -->
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <title>{{ $title ?? 'Page Title' }}</title>

        @livewireStyles
    </head>
    <body>
        {{ $slot }}

        @livewireScripts
    </body>
</html>

然后,在你的组件视图中,在根元素外部定义一个 <x-slot> 元素:

blade
<x-slot:lang>fr</x-slot> // 此组件使用法语 <!-- [tl! highlight] -->

<div>
    // 法语内容放在这里...
</div>

访问路由参数

在处理页面组件时,你可能需要在 Livewire 组件内访问路由参数。

为了演示,首先在 routes/web.php 文件中定义一个带有参数的路由:

php
Route::livewire('/posts/{id}', 'pages::show-post');

在这里,我们定义了一个带有 id 参数的路由,它代表文章的 ID。

接下来,更新你的 Livewire 组件以在 mount() 方法中接收路由参数:

php
<?php

use App\Models\Post;
use Livewire\Component;

new class extends Component
{
    public Post $post;

    public function mount($id) // [tl! highlight]
    {
        $this->post = Post::findOrFail($id);
    }
};

在此示例中,因为参数名称 $id 与路由参数 {id} 匹配,如果访问 /posts/1 URL,Livewire 将传递值"1"作为 $id

使用路由模型绑定

Laravel 的路由模型绑定允许你从路由参数自动解析 Eloquent 模型。

routes/web.php 文件中定义带有模型参数的路由后:

php
Route::livewire('/posts/{post}', 'pages::show-post');

你现在可以通过组件的 mount() 方法接收路由模型参数:

php
<?php

use App\Models\Post;
use Livewire\Component;

new class extends Component
{
    public Post $post;

    public function mount(Post $post) // [tl! highlight]
    {
        $this->post = $post;
    }
};

Livewire 知道使用"路由模型绑定",因为 Post 类型提示被添加在 mount() 中的 $post 参数之前。

像之前一样,你可以通过省略 mount() 方法来减少样板代码:

php
<?php

use Livewire\Component;
use App\Models\Post;

new class extends Component
{
    public Post $post; // [tl! highlight]
};

$post 属性将自动分配给通过路由的 {post} 参数绑定的模型。