基于 Laravel Jetstream 提供的 Livewire + Blade 技术栈编写表单组件


Livewire 简介

上篇教程学院君给大家介绍了 Laravel 8 新引入的 Jetstream 扩展包,并且提到该扩展包开箱提供了两种前端组件开发技术栈,以便降低新手入门前端页面组件开发的门槛,第一种是基于 Livewire + Blade 组合,第二种是 Inertia + Vue 组合,后一种技术方案我们上篇教程已经演示过,今天我们来看第一种。

关于 Livewire 框架学院君去年已经写过相关的介绍教程:

简而言之,Livewire 可以通过纯 PHP 代码实现前端页面组件的渲染,不需要编写任何 JavaScript 代码,是在 Laravel 框架中完全基于 PHP 进行全栈开发的必备良品。

使用 Livewire + Blade 编写单页面组件

初始化 Jetstream + Livewire

假设你已经有了一个 Laravel 8 项目,使用 Jetstream 之前,首先要通过 Composer 安装这个扩展包(已安装跳过这一步):

composer require laravel/jetstream

注:如果你使用 Laravel 安装器安装 Laravel 8 的话(安装器版本必须是 4.0+),还可以在安装的时候通过 --jet 选项指定安装 Jetstream 依赖,这样,就不需要再通过上面的 composer 命令再次安装它了:laravel new blog --jet

接下来,我们需要在 Jetstream 中安装 Livewire 技术栈:

php artisan jetstream:install livewire

Inertia 一样,执行下面两条命名进行必要资源的初始化工作:

npm install && npm run dev

php artisan migrate

完成以上初始化工作后,你可以使用如下命令将 Jetstream 自带的 Blade 组件发布到视图模板目录下:

php artisan vendor:publish --tag=jetstream-views

基于 Livewire 编写表单组件

注:开始之前,你可以先阅读 LivewireBlade 官方文档了解基本开发流程。

我们使用 Livewire 提供的 Artisan 命令新建文章发布表单组件(这里演示的功能和上篇教程完全一致,只是改用 Livewire + Blade 技术栈实现):

php artisan livewire:make PostCreateForm

该命令会创建对应的后端组件类和前端视图模板文件:

-w771

编写 PostCreateForm 组件类代码如下:

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class PostCreateForm extends Component
{
    public $title;
    public $author = [];
    public $body;

    protected $rules = [
        'title' => 'required|max:255',
        'author.name' => 'required',
        'body' => 'required',
    ];

    public function render()
    {
        return view('livewire.post-create-form');
    }

    public function storePostInformation()
    {
        $this->validate();
        
        // 保存文章信息操作
    }
}

我们通过组件类的公共属性定义组件数据(对应 Vue 组件的 data 属性),通过 render 方法渲染对应的组件模板视图(对应 Vue 组件的 template 模板),如果该组件与后端有交互,可以定义额外的方法(对应 Vue 组件的 methods 方法集),比如这里定义了 storePostInformation 方法处理表单提交,我们可以在这里调用组件基类提供的表单验证方法对表单数据进行验证(和 HTTP 控制器类似),如果验证失败,会在前端渲染对应的错误信息,非常方便。

基于 Blade 渲染 Livewire 组件

接下来,我们编写 post-create-form.blade.php 前端组件模板代码如下:

<x-jet-form-section submit="storePostInformation">
    <x-slot name="title">
        发布新文章
    </x-slot>
    <x-slot name="description">
        这里是发布新文章页面
    </x-slot>


    <x-slot name="form">
        <div class="col-span-6 sm:col-span-6">
            <x-jet-label for="title" value="标题" />
            <x-jet-input name="title" type="text" wire:model="title" class="mt-1 block w-full"/>
            <x-jet-input-error for="title" class="mt-2" />
        </div>

        <div class="col-span-6 sm:col-span-6">
            <x-jet-label for="author" value="作者" />
            <x-jet-input name="author[name]" type="text" wire:model="author.name" class="mt-1 block w-full"/>
            <x-jet-input-error for="author.name" class="mt-2" />
        </div>

        <div class="col-span-6 sm:col-span-6">
            <x-jet-label for="body" value="内容" />
            <textarea rows="5" name="body" class="form-input rounded-md shadow-sm mt-1 block w-full">{{ $body }}</textarea>
            <x-jet-input-error for="body" class="mt-2" />
        </div>
    </x-slot>

    <x-slot name="actions">
        <x-jet-button>
            立即发布
        </x-jet-button>
    </x-slot>
</x-jet-form-section>

在这里,我们引用了 Jetstram 内置的表单组件 x-jet-form-section 来构建文章发布表单组件,这些内置组件位于 resources/views/vendor/jetstream/components 目录下(如果你前面运行过 vendor:publish 命令发布过的话),使用 Blade 组件需要在组件名之前加上 x- 前缀以示区分。

在 Jetstream 中,可以通过内置的 x-jet-input-error 组件渲染表单字段验证错误消息。

最后,创建 post/create.blade.php 视图模板代码,通过 @livewire 指令引入文章发布表单组件:

<x-app-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            文章管理
        </h2>
    </x-slot>

    <div>
        <div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
            @livewire('post-create-form')

            <x-jet-section-border />
        </div>
    </div>
</x-app-layout>

这个视图模板继承了 Jetstream 提供的 x-app-layout 布局。

编写后端路由和控制器代码

最后,我们需要在 Laravel 应用后端注册路由和对应的控制器方法,来完成前端页面组件的渲染以及与后端的接口交互。

上篇教程的基础上,我们修改 PostController 控制器代码如下:

<?php

namespace App\Http\Controllers;

class PostController extends Controller
{
    public function create()
    {
        return view('post.create');
    }
}

只需要渲染创建文章页面模板视图即可,相应的,路由注册文件 routes/web.php 中也只需要注册 post/create 路由:

Route::group(['middleware' => ['auth', 'verified']], function () {
    Route::get('/post/create', [PostController::class, 'create']);
});

体验基于 Livewire + Blade 编写的页面组件渲染

Blade 表单组件渲染和提交

刷新文章发布界面,就可以看到重构后的视图渲染效果了:

-w1042

和基于 Inertia + Vue 实现的效果完全一致:

-w843

在 Livewire 和 Inertia 之间切换

如果你同时安装了 Inertia 和 Livewire,想要在它们之间切换,可以在 config/jetstream.php 配置文件中修改 stack 配置项实现:

/*
|--------------------------------------------------------------------------
| Jetstream Stack
|--------------------------------------------------------------------------
|
| This configuration value informs Jetstream which "stack" you will be
| using for your application. In general, this value is set for you
| during installation and will not need to be changed after that.
|
*/

'stack' => 'livewire',

注:更多 Jetstream 使用细节请参考 Jetstream 文档


点赞 取消点赞 收藏 取消收藏

<< 上一篇: 基于 Laravel Jetstream 提供的 Inertia + Vue 技术栈编写表单组件

>> 下一篇: 前奏篇(一):ES 2015 新特性一览