在 Vue 中捕获 Laravel 验证错误

发布日期:作者:

Catching Laravel Validation Errors in Vue image

验证是一种确保从前端表单或请求提交的数据满足您的预期并确保我们在数据库中存储正确数据的方式。当提交表单或请求时,在我们使用该数据运行任何逻辑之前,我们需要确保它满足我们所有的要求。如果数据不满足我们的要求,我们需要告诉用户他们提交的数据有问题,以便他们可以修复它。

项目

目前,我正在开发一个名为 SavvyHouseHunting.com 的 SAAS 应用程序 - 它是一个平台,允许房地产经纪人创建和分享 360 度视频和图像、文档以及与客户的邮件。该应用程序的一个关键区别在于它是一个 Vue SPA,利用 Vue Router,因此我们无法像在 Blade 视图中那样使用 Blade 助手 @errors

在网站的一个区域,允许某些类型的用户“邀请”其他人加入他们的团队;在收到邀请后,用户需要提供一些必要的用户数据才能开始使用。

入门

首先,由于我们不希望用户多次接受邀请,在生成邀请邮件时,我们创建了一个 已签名 URL,如下所示

$invitation = Invitation::create([
'to' => request('email'),
'user_id' => auth()->user()->id,
'type' => request('type')
]);
 
$link = URL::signedRoute('accept-invitation', ['invitation' => $invitation->id]);
Mail::to(request('email'))->send(new InvitationMail(auth()->user(), $link));

邮件将发送给被邀请的用户,其中包含已签名的 URL,当用户点击邮件中的链接时,我们会收到该请求并渲染我们的表单。但是,为了确保签名有效,我们可以使用一个简单的 abort_if 方法,该方法接受一个布尔值、一个 HTTP 状态码以及一个可选的消息发送回用户。

更多逻辑

此外,我们需要查找 invitation 并确保它尚未被接受,模型上有一个 accepted 列,我们将在稍后的过程中将其标记为 true。允许的一个额外注意事项是在此被邀请的用户实际上已经在我们的系统中存在的场景中,也许他们也属于其他人的团队。以下是 accept 方法

abort_if(!request()->hasValidSignature(), 403, 'YOU CAN\'T DO THAT');
$invitation = Invitation::find(request('invitation'));
abort_if($invitation->accepted, 403, 'That invitation has already been accepted');
 
$from = User::find($invitation->user_id);
try {
$user = User::where('email', $invitation->to)->firstOrFail();
$this->createAssociations($user, $invitation, $from);
$invitation->accepted = true;
$invitation->save();
auth()->login($user);
return redirect('/dashboard/communication');
} catch (ModelNotFoundException $m) {
return view('invitation.accept', compact('invitation'));
}

您可以看到我们正在遍历多个实例进行验证。如果请求没有有效的签名,则中止;查找邀请并中止如果它已经被接受;获取被邀请人的电子邮件并在数据库中尝试找到他们;如果是,则可以;创建与邀请人之间的新的关联;将邀请标记为 accepted;将他们登录到应用程序并重定向到仪表板;如果不是,Laravel 将抛出一个 ModelNotFoundException。我们可以使用 invitation 对象将他们发送到我们的表单。

实例化组件很简单,我们只需要将邀请作为道具传递

<accept-invitation :invitation="{{$invitation}}"></accept-invitation>

在 Vue 中处理 Laravel 错误

Vue 表单有点长,但本质上,我们将邀请传递到 Vue 组件并将邀请对象添加到隐藏字段,并实例化我们对用户的期望

props: {
invitation: {
type: Object,
required: true,
},
},
data() {
return {
user: {
first_name: '',
last_name: '',
email: '',
phone_number: '',
password: '',
password_confirmation: '',
},
errors: null,
};
},

errors 对象是我们将放置从 post 请求捕获的任何错误的地方。我使用 Tailwind 进行所有样式,div 看起来像这样

<div v-if="errors" class="bg-red-500 text-white py-2 px-4 pr-0 rounded font-bold mb-4 shadow-lg">
<div v-for="(v, k) in errors" :key="k">
<p v-for="error in v" :key="error" class="text-sm">
{{ error }}
</p>
</div>
</div>

最后,是 post 方法

methods: {
submit() {
axios
.post('accept-invitation', {
user: this.user,
invitation: this.invitation
})
.then(data => {
location.href = '/dashboard/communication';
})
.catch(e => {
this.errors = e.data.errors;
});
},
},

让我们看看处理此请求的控制器方法

Route::post('accept-invitation', 'InvitationController@submit');

Laravel 表单请求验证

对于此方法,由于我们将多个字段传递给控制器,因此让我们利用 Laravel 的表单请求,这里我们使用两种方法:rules()messages(),如下所示

public function rules()
{
return [
'user.first_name' => ['required', 'string', 'max:255', 'min:2'],
'user.last_name' => ['required', 'string', 'max:255'],
'user.phone_number' => ['required', 'max:255'],
'invitation.type' => ['required', 'string', 'max:255'],
'invitation' => ['required'],
'user.password' => ['required', 'min:6', 'confirmed'],
];
}
 
public function messages()
{
return [
'user.first_name.required' => 'Your first name is required',
'user.first_name.min' => 'Your first name must be at least 2 characters',
'user.first_name.max' => 'Your first name cannot be more than 255 characters',
'user.first_name.string' => 'Your first name must be letters only',
 
'user.last_name.required' => 'Your last name is required',
'user.last_name.min' => 'Your last name must be at least 2 characters',
'user.last_name.max' => 'Your last name cannot be more than 255 characters',
'user.last_name.string' => 'Your last name must be letters only',
 
'user.phone_number.required' => 'Your phone number is required',
'user.phone_number.max' => 'Your phone number cannot be more than 255 characters',
 
'user.password.required' => 'You must create a password',
'user.password.min' => 'Your password must be at least 6 characters long',
'user.password.confirmed' => 'Your password confirmation does not match',
];
}

让我们测试一下,看看如果我们传递一个不匹配的密码会得到什么

瞧!我们能够轻松地在 Vue 表单中解析 Laravel 验证错误!

专业提示!

我看到很多人没有做的一件事是在他们的控制器中使用验证后的数据,而不是请求数据。一旦数据被验证,您就可以将其设置为一个仅包含作为数组验证数据的变量。

$validated = $request->validated();

通常,我看到开发人员验证请求,然后使用请求数据,并假设由于验证通过,数据是正确的。但是,如果您忘记验证一个字段呢?您的验证将通过,但数据可能不好。这种方法将使您的验证更强大,并提高您的代码信心!

Shane D Rosenthal photo

我是一个科技迷、家庭男人、社区领导人、飞行员和音乐家。从 80 年代中期开始,我就一直拆卸东西,看看它们是如何工作的,并试图将它们重新组装起来,有时比以前状态更好。一路上,我遇到了我生命中的爱人,组建了家庭,在领导和指导他人方面找到了目标,最近还成为了一名飞行员。我对飞行、与周围的人分享世界以及尽可能地观看现场金属音乐表演充满热情。

展望未来,我打算拥有自己的飞机,保持仪表等级,继续教导和指导我们的年轻人,发展我的 YouTube 频道和粉丝,并分享我的热情,影响我能影响的任何人。

分类
Cube

Laravel 新闻通讯

加入 40,000 多名其他开发人员,不错过任何新的技巧、教程等。

Laravel Forge logo

Laravel Forge

轻松创建和管理您的服务器,并在几秒钟内部署您的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动补全和对本地和生产环境的即时反馈进行调整。

Tinkerwell
No Compromises logo

绝不妥协

Joel 和 Aaron,来自 No Compromises 播客的两位经验丰富的开发人员,现可为您的 Laravel 项目提供服务。 ⬧ 固定费率 7500 美元/月。 ⬧ 无冗长的销售流程。 ⬧ 无合同。 ⬧ 100% 返款保证。

绝不妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,确保您的 Web 应用程序成功。

Kirschbaum
Shift logo

Shift

运行旧版 Laravel 版本?即时、自动化的 Laravel 升级和代码现代化,让您的应用程序保持新鲜。

Shift
Bacancy logo

Bacancy

只需每月 2500 美元,即可获得一位拥有 4-6 年经验的资深 Laravel 开发人员,为您的项目提供强力支持。获得 160 小时的专业服务,并享有 15 天无风险试用。立即预约电话!

Bacancy

Lucky Media logo

幸运媒体

幸运即刻 - Laravel 开发的理想选择,拥有十多年的经验!

幸运媒体
Lunar: Laravel E-Commerce logo

Lunar:Laravel 电子商务

Laravel 电子商务。一个开源软件包,将现代无头电子商务功能的强大功能带到 Laravel。

Lunar:Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 招聘网站

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit:Laravel SaaS 启动工具包

SaaSykit 是一个 Laravel SaaS 启动工具包,包含运行现代 SaaS 所需的所有功能。支付、漂亮结账、管理面板、用户仪表板、身份验证、即用组件、统计数据、博客、文档等等。

SaaSykit:Laravel SaaS 启动工具包
Rector logo

Rector

您无缝升级 Laravel、降低成本和加速创新的合作伙伴,帮助企业取得成功。

Rector
MongoDB logo

MongoDB

通过 MongoDB 和 Laravel 的强大集成来增强您的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。支持事务、搜索、分析和移动用例,同时使用熟悉的 Eloquent API。了解 MongoDB 的灵活、现代数据库如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单的零依赖输入掩码库。

阅读文章
Add Swagger UI to Your Laravel Application image

将 Swagger UI 添加到您的 Laravel 应用程序

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel Prompts 构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的网站搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 包为您的 Laravel 应用程序添加评论

阅读文章