2、 Livewire 组件式开发,复用的利器
hi,我是温新,一名 PHPer
在 Livewire 中,组件是用来构建应用程序的一个模块。比如,我们有一个 “五星评价” 的小功能,把这个功能抽离成单独的组件,那么当某个需要使用“五星评价”功能的功能时,直接在该页面中引入这个组件即可。
关于组件的创建与使用也非常简单,我们来看看。
组件的创建与使用
1)创建组件
$ php artisan make:livewire create-post
命令执行成功后看到如下信息:
CLASS: app/Livewire/CreatePost.php
VIEW: resources/views/livewire/create-post.blade.php
该信息告诉了我们,命令执行后生成了什么文件以及文件的位置。关于文件中的内容,暂时不看,先来使用它。
2)修改模板
resources/views/livewire/create-post.blade.php
<div>
Create Post
</div>
3)使用组件
组件渲染语法:<livewire:component-name />
我们可以使用该语法,在需要使用组件的模板中引入组件。现在, 我们在 welcome.blade.php
模板中引入 create-post
组件。
resources/views/welcome.blade.php
...
<body class="antialiased">
<!-- 在 welcome 模板中使用 create-post 组件 -->
<livewire:create-post/>
</body>
...
打开浏览器看看效果吧。
4)扩展篇
在上面的方法中,创建组件使用的是中划线
的方式,我们还可以使用驼峰法
的方式来创建组件。二者之间,生成的文件是一样的,只是写法有所区别。
# 执行
$ php artisan livewire:make test-add
# 执行,会提示文件已存在
$ php artisan livewire:make TestAdd
使用目录来规划我们的组件
任何事情都怕一个“多”字,我们的项目也是如此。一旦文件多起来且没有合理的规划时,那么将是一个灾难。来看看我们的项目中都有哪些文件了。
$ tree app/Livewire/
app/Livewire/
├── CreatePost.php
├── TestAdd.php
└── Test.php
$ tree resources/views/livewire/
resources/views/livewire/
├── create-post.blade.php
├── test-add.blade.php
└── test.blade.php
下面我们开始对目录进行改造。
1)使用目录来规划组件
创建目录的方式有两种,一种是命名空间的形式
,另一种是.
的形式,如下:
# 点 形式
$ php artisan livewire:make posts.create-post
$ php artisan livewire:make tests.test
# 命名空间形式
$ php artisan livewire:make Tests\\TestAdd
改造完成后,我们删除不必要的文件后,再来看看现在的文件结构:
$ tree app/Livewire/
app/Livewire/
├── Posts
│ └── CreatePost.php
└── Tests
├── TestAdd.php
└── Test.php
$ tree resources/views/livewire/
resources/views/livewire/
├── posts
│ └── create-post.blade.php
└── tests
├── test-add.blade.php
└── test.blade.php
2)修改 create-post
组件内容
resources/views/livewire/posts/create-post.blade.php
<div>
Posts/CreatePost
</div>
3)修改 welcome 模板
resources/views/welcome.blade.php
...
<body class="antialiased">
<!-- 引入组件 -->
<!-- 当有目录时,模板渲染格式为:目录.组件名 -->
<livewire:posts.create-post/>
</body>
...
修改完成后,通过浏览器访问看看效果吧。
全页组件
了解单页组件之前,我们先来回顾一下前面使用组件的方法。
1、模板:现在来看看 welcome.blade.php
这个模板,在这里我们可以看到它使用了 create-post
这个 livewire 组件
2、路由:再来看看 welcome 模板的路由:
// routes/web.php
Route::get('/', function () {
return view('welcome');
});
3、简单的流程梳理:
- 3.1、当访问路由
localhos
时,会去加载welcome
视图模板; - 3.2、而我们在
welcome
视图模板中引入了 livewire 中的posts.create-post
组件,然后渲染该组件内容,我们就可以在浏览器中看到组件的内容了。
那么,问题来了,我们是一个模板中引入了组件,因此它就输出组件的内容了。
现在,我们要在浏览器中单独渲染一个组件内容(如:用户列表),此时,该我们做呢?当然了,也可以使用和上面操作的相同方法来渲染用户列表。但是,要单独渲染用户列表,该怎么操作?
1)创建组件
$ php artisan livewire:make users.user
2)添加路由
Livewire 允许在 Laravel 应用程序中直接将组件分配给路由。
// web.php
...
Route::get('users', \App\Livewire\Users\User::class);
现在,我们来访问一下这个路由:http://livewirev3.test/users
,如果出现了如下错误,那么,恭喜你,我这是故意的。
错误:
Livewire page component layout view not found: [components.layouts.app]
通过这个错误,我们可以发现,是缺少了 layouts.app
组件。
出现这个错误的原因是因为我们使用了全页组件
,当使用了全页组件时,那么就必须使用一个布局组件 resources/views/components/layouts/app.blade.php
。
我们可以自定义这个布局组件,也可以使用命令来创建,下面我们使用命令来生成布局组件。
3)生成布局组件
$ php artisan livewire:layout
命令执行完成后就可以在浏览器访问了,由于我们没有填写任何内容,因此会看到一个空白页面。
我们查看一个生成的布局文件,并进行修改:
resources/views/components/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 ?? '自如初' }}</title>
</head>
<body>
<!-- 内容插槽 -->
{{ $slot }}
</body>
</html>
4)修改用户列表组件
resources/views/livewire/users/user.blade.php
<div>
UserList
</div>
修改完成后,浏览器中访问看看效果吧:http://livewirev3.test/users
使用自定义布局组件
有时候,并不是所有的文件都要继承同一个组件,此时,可以使用自定义布局组件将其分开,A 就继承 A 的布局组件,B 就继承 B 的布局组件。下面我们来操作一下。
1)添加一个自定义布局组件
resources/views/components/layouts/app-test.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 ?? '测试自定义布局组件' }}</title>
</head>
<body>
<h2>自定义测试布局组件</h2>
{{ $slot }}
</body>
</html>
2)添加路由
routes/web.php
...
Route::get('tests', \App\Livewire\Tests\Test::class);
3)使用自定义布局组件
Livewire/Tests/Test.php
<?php
namespace App\Livewire\Tests;
use Livewire\Attributes\Layout;
use Livewire\Component;
class Test extends Component
{
#[Layout('components/layouts/app-test')]
public function render()
{
return view('livewire.tests.test');
}
}
4)效果对此
浏览器中访问 http://livewirev3.test/tests
和 http://livewirev3.test/users
,就会看到不同的内容,这就是它们使用了不同的布局组件。