Day 17 | 常用范例:前後端共用的表单输入验证 Validate

Livewire 大致上功能都已经介绍完了,接下来就是一些常用的实作时间啦!!今天要来做最常会遇到的 表单验证 功能!!以往这个功能在使用者输入了格式错误的资料,要提醒使用者时
若要做到像Google表单的话实在是非常麻烦,光是用 jQuery 在调整显示错误的 DOM 就要花上好多时间。不过有了 Livewire 做这些事就像喝水一样快!!

DEMO页面
GitHub

https://ithelp.ithome.com.tw/upload/images/20210919/20111805fSAsSVnmnz.png

今天的目标

今天就来做简单的使用者基本资料表单好了!! 我这边是用 tailwindcss 加上 semantic-ui ,大家可以用自己习惯的。首先先刻好一个简单的前端页面。

注:不推 semantic-ui,会用他只是 UI 上看起来比较 light 加上 tailwindcss 没有 <input><button>之类现成的 class。要使用 UI 框架还是推荐 boostrap 。

<div class="text-center p-5">
    <h2 class="mb-10">Day17 常用范例:前後端共用的表单输入验证</h2>

    <div class="flex justify-center mt-5">
        <div class="rounded shadow-md bg-grey-50 border-2 w-96 p-4 px-8 text-left">
            <div class="ui form my-5">
                <h4 class="ui dividing header mb-2">请输入用户资料</h4>
                <div class="field">
                    <label>姓名</label>
                    <input type="text">
                </div>
                <div class="field">
                    <label>手机号码</label>
                    <input type="text">
                </div>
                <div class="field">
                    <label>Email</label>
                    <input type="text">
                </div>
            </div>
            <div class="text-center">
                <button class="ui button">下一步</button>
            </div>
        </div>
    </div>

</div>

设定後端

後端的部分很单纯,先宣告一下 <input> 要填的变数,之後再宣告一个 $rules 并分别设定要验证的内容。

$rules 功能来自 Larave Validation ,使用起来非常简单好用,如要找更多的验证条件可以详见这边

这边分别设定了:
栏位 验证
name 必填,最少三字
phone 必填,数字十位
email 必填,email格式
以及保存的 Function: save()

透过 $this->validate() ,可以直接验证所有 $rules 的内容。由於范例没有真的要写入资料库,因此下一行就先注解掉!

<?php

namespace App\Http\Livewire\Example;

use Livewire\Component;

class Day17 extends Component
{
    public $name;
    public $phone;
    public $email;

    public $rules = [
        'name' => 'required|min:3',
        'phone' => 'required|digits:10',
        'email' => 'required|email'
    ];

    public function render()
    {
        return view('livewire.example.day17');
    }

    public function save()
    {
        $validatedData = $this->validate();

        // User::create($validatedData);
    }
}

前端补上 Livewire 的内容

这边希望按下按钮後才会触发更新,所以所有的 <input> 中都使用 wire:model.defer

 <div class="ui form my-5">
    <h4 class="ui dividing header mb-2">请输入用户资料</h4>
    <div class="field">
        <label>姓名</label>
        <input type="text" wire:model.defer="name">
    </div>
    <div class="field">
        <label>手机号码</label>
        <input type="text" wire:model.defer="phone">
    </div>
    <div class="field">
        <label>Email</label>
        <input type="text" wire:model.defer="email">
    </div>
</div>
<div class="text-center">
    <button class="ui button" wire:click="save">下一步</button>
</div>

加上验证失败的显示

前端要显示错误主要有两种方法,一种是透过 @error 另一种则是 $error->has

这里分别应用了这两种,分别是添加 ClassName:

class="{{ $errors->has('name') ? 'error' : '' }}"

以及显示错误讯息:

@error('name')
    <span>*最少3个字</span>
@enderror

完整的前端页面如下:

<div class="field {{ $errors->has('name') ? 'error' : '' }}">
    <label>姓名</label>
    <input type="text" wire:model.defer="name">
    @error('name')<span class="text-red-500">*最少3个字</span>@enderror
</div>
<div class="field {{ $errors->has('phone') ? 'error' : '' }}">
    <label>手机号码</label>
    <input type="text" wire:model.defer="phone">
    @error('phone')<span class="text-red-500">*需为数字10码</span>@enderror
</div>
<div class="field {{ $errors->has('email') ? 'error' : '' }}">
    <label>Email</label>
    <input type="text" wire:model.defer="email">
    @error('email')<span class="text-red-500">*email格式不符合</span>@enderror
</div>
</div>
<div class="text-center">
	<button class="ui button" wire:click="save">下一步</button>
</div>

到这边一个表单的验证就完成啦!!


如果要改成即时验证

如果觉得送出时才做错误验证还不够,那可以使用这个方法!

先在後端加入

当 model 触发更新时会透过 $this->validateOnly($propertyName) 来该对象验证更新後的内容。

注:生命周期勾中的 update 只会对 model 所做的修改进行触发。

public function updated($propertyName)
{
    $this->validateOnly($propertyName);
}

前端修改

之後把 <input>wire:model.defer 改成 wire:model.lazy 这样在滑鼠离开输入匡的时候就会验证罗!!当然如果打一个字就验证一次的话可以单纯使用 wire:model 就好罗!

改成 .lazy 後的DEMO

当然还有更多表单验证的玩法,可以参考官方文件

<<:  C# 一些特性

>>:  #04 No-code 之旅 — Next.js 中的 Pre-render 与 Data Fetching

[Day8] Vite 出小蜜蜂~撞击检测 Collision Detection!

Day8 Collision Detection 接下来我们要让 Laser 打中敌人时,将敌人消灭...

Day23

函数指标只要参数与返回值相同是可以随时指向一个新的函数如前所说的max, min,当然C++作为那个...

[Day 30] 完赛心得 — 大家可以回家啦

完赛心得 转眼间就过了 30 天啦,第一次参赛有够菜没想到还能迎来这一天。 要坚持每天发文真的很考验...

DAY 24 『 客制化文字输入框 Custom TextField 』

昨天介绍完客制化按钮,今天会分享客制化文字输入框( 加入图示、图示显示在左边或右边 ) 成品: 刻好...

Day18 Lab 2 - Object storage metadata

Object的metadata让我们能快速定位Object在什麽地方、属性等等,可以理解为类似资料库...