渲染组件

未匹配的标注

渲染组件

内联组件

在页面上渲染 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

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
贡献者:2
讨论数量: 0
发起讨论 查看所有版本


暂无话题~