渲染组件
渲染组件
内联组件
在页面上渲染 Livewire 组件的最基本方法是使用 <livewire:
标记语法:
<div>
<livewire:show-posts />
</div>
同样地,您也可以使用 @livewire
Blade 指令:
@livewire('show-posts')
如果您的组件放在子文件夹中,具有自己命名空间,则必须使用一个以命名空间为前缀的点(.
)。
例如,如果我们在 app/Http/Livewire/Nav
目录下有一个 ShowPosts
组件,我们会这样表示它:
<livewire:nav.show-posts />
参数
传递参数
您可以通过将其他参数传递给 <livewire:
标记来将数据传递到组件中。
例如,假设我们有一个 show-post
组件。这里展示了您如何传递 $post
模型。
<livewire:show-post :post="$post">
同样地,这里展示了您如何通过 Blade 指令传递参数。
@livewire('show-post', ['post' => $post])
接收参数
Livewire 会自动将参数分配给匹配的公共属性。
例如,在 <livewire:show-post :post="$post">
的情况下,如果 show-post
组件具有名为 $post
的公共属性,则会自动为其赋值:
class ShowPost extends Component
{
public $post;
...
}
如果出于某种原因,自动分配机制不能正常工作,那么你可以使用 mount()
方法截获参数:
class ShowPost extends Component
{
public $title;
public $content;
public function mount($post)
{
$this->title = $post->title;
$this->content = $post->content;
}
...
}
在 Livewire 组件中,您应使用
mount()
替代类构造函数__construct()
。
特别注意:mount()
仅在首次挂载组件时调用,此后即使组件再次刷新或重新渲染也不会再次调用。
类似控制器, 您可以通过新增类型声明参数来进行依赖注入。
use \Illuminate\Session\SessionManager;
class ShowPost extends Component
{
public $title;
public $content;
public function mount(SessionManager $session, $post)
{
$session->put("post.{$post->id}.last_viewed", now());
$this->title = $post->title;
$this->content = $post->content;
}
...
}
整页组件
如果页面地主体内容是一个 Livewire 组件,您可以将该组件直接传递至 Laravel 路由中,就像它是控制器一样。
Route::get('/post', ShowPosts::class);
默认情况下,Livewire 会将 ShowPosts
组件渲染到位于以下位置的布局组件的 {{ $slot }}
中:resources/views/layouts/app.blade.php
<head>
@livewireStyles
</head>
<body>
{{ $slot }}
@livewireScripts
</body>
更多关于 Laravel 组件的信息,请 查看 Laravel 文档。
配置组件布局
如果要指定 layouts.app
以外的默认布局,可以覆盖 livewire.layout
配置选项。
'layout' => 'app.other_default_layout'
如果您需要更强的控制性,你可以在 render()
返回的视图实例上使用 ->layout()
方法。
class ShowPosts extends Component
{
...
public function render()
{
return view('livewire.show-posts')
->layout('layouts.base');
}
}
如果您的布局具有关联的类文件,则需要为任何自定义逻辑或属性引用该文件。
class ShowPosts extends Component
{
...
public function render()
{
return view('livewire.show-posts')
->layout(\App\View\Components\BaseLayout::class);
}
}
如果您在组件中使用非默认插槽,您还可以链式调用 ->slot()
:
public function render()
{
return view('livewire.show-posts')
->layout('layouts.base')
->slot('main');
}
同样地,Livewire 支持使用带有 @extends
的传统 Blade 布局文件。
给定以下布局文件:
<head>
@livewireStyles
</head>
<body>
@yield('content')
@livewireScripts
</body>
您可以配置 Livewire 以使用 ->extends()
代替 ->layout()
引用:
public function render()
{
return view('livewire.show-posts')
->extends('layouts.app');
}
如果您需要配置组件的 @section
来使用,也可以使用 ->section()
方法进行配置:
public function render()
{
return view('livewire.show-posts')
->extends('layouts.app')
->section('body');
}
如果您需要将数据从组件传递到布局,可以将数据与 layout
方法一起传递:
public function render()
{
return view('livewire.show-posts')
->layout('layouts.base', ['title' => 'Show Posts'])
}
如果在某些情况下,您不需要传递布局名称,或者想要单独传递布局数据,可以使用 layoutData
方法:
public function render()
{
return view('livewire.show-posts')
->layoutData(['title' => 'Show Posts'])
}
路由参数
您可能经常在控制器里访问路由参数。由于不再使用控制器,所以 Livewire 试图通过 mount
方法来模仿这种行为。 例如:
Route::get('/post/{id}', ShowPost::class);
class ShowPost extends Component
{
public $post;
public function mount($id)
{
$this->post = Post::find($id);
}
...
}
正如您所看到的,就其参数而言,Livewire 组件中的 mount
方法的行为就像控制器方法一样。 如果您访问 /post/123
,则传递给 mount
方法的 $id
变量将包含值 123
。
路由模型绑定
就像您期望的那样,Livewire 组件实现了您在控制器中惯用的所有功能,包括路由模型绑定。例如:
Route::get('/post/{post}', ShowPost::class);
class ShowPost extends Component
{
public $post;
public function mount(Post $post)
{
$this->post = $post;
}
}
如果您使用的是 PHP 7.4,您还可以声明类属性,Livewire 将自动进行路由模型绑定。以下组件 $post
的属性将自动注入,无需使用 mount()
方法。
class ShowPost extends Component
{
public Post $post;
}
渲染方法
在页面初始加载和随后组件更新时,将调用 Livewire 组件的 render
方法。
在简单的组件中,您不需要自己定义
render
方法。 Livewire 组件基类包含一个动态的render
方法。
返回 Blade 视图
render()
方法应当返回一个 Blade 视图,因此,您可以将其与编写控制器方法进行比较。这里是一个例子:
确保您的 Blade 视图只有一个根元素。
class ShowPosts extends Component
{
public function render()
{
return view('livewire.show-posts', [
'posts' => Post::all(),
]);
}
}
<div>
@foreach ($posts as $post)
@include('includes.post', $post)
@endforeach
</div>
返回模板字符串
除了 Blade 视图以外,您也可以选择在 ->render()
方法中返回一个 Blade 模板字符串。
class DeletePost extends Component
{
public Post $post;
public function delete()
{
$this->post->delete();
}
public function render()
{
return <<<'blade'
<div>
<button wire:click="delete">Delete Post</button>
</div>
blade;
}
}
对于类似上述的内联组件,您应该在创建过程中使用 --inline
参数:
artisan make:livewire delete-post --inline