In this post, I will be showing you how to handle Laravel validation error messages with Vue.js.
在本文中,我将向您展示如何使用Vue.js处理Laravel验证错误消息。
Recently, I launched a open source side project I was working on called Open Laravel. Open Laravel allows developers to submit open source projects that were built using the Laravel framework. The project submission page uses Vue.js to submit the form asynchronously through an AJAX
request. Since I am no longer sending the form the default way (refreshing after form submission), I needed a way to show Laravel form validation error messages. After going back and forth with some forum questions and answers, I was able to make it work.
最近,我启动了一个正在进行的开源项目Open Laravel 。 Open Laravel允许开发人员提交使用Laravel框架构建的开源项目。 项目提交页面使用Vue.js通过AJAX
请求异步提交表单。 由于我不再以默认方式发送表单(提交表单后刷新),因此我需要一种显示Laravel表单验证错误消息的方法。 在来回讨论一些论坛的问题和答案之后,我得以使其工作。
How I solved this is what I'll be showing you in this tutorial. A quick demo is shown below.
在本教程中,我将向您展示如何解决这个问题。 快速演示如下所示。
让我们开始 ( Let's Begin )
I'll be using a basic post creation demo for this tutorial. I'll start with a fresh installation of Laravel. I named the demo vuejs-laravel-validation-error-messages
, feel free to name it whatever you like.
我将在本教程中使用基本的帖子创建演示。 我将从全新安装Laravel开始。 我将其命名为演示vuejs-laravel-validation-error-messages
,可以随意命名。
laravel new vuejs-laravel-validation-error-messages
For this tutorial, we'll be making use of Laravel Elixir
. Laravel Elixir is tool that allows you perform Gulp tasks inside your Laravel applications.
在本教程中,我们将使用Laravel Elixir
。 Laravel Elixir是允许您在Laravel应用程序中执行Gulp任务的工具。
More on it can be found on Laravel Elixir. We'll be using Laravel Elixir to build and compile the JavaScript we will be writing. So before anything, we need to install Laravel Elixir dependencies:
有关更多信息,请参见Laravel Elixir 。 我们将使用Laravel Elixir构建和编译将要编写JavaScript。 因此,在进行任何操作之前,我们需要先安装Laravel Elixir依赖项:
npm install
项目依赖 ( Project Dependencies )
Having installed Laravel Elixir dependencies, it time to define and install the project dependencies. We'll be making use of the following:
安装了Laravel Elixir依赖项之后,就该定义和安装项目依赖项了。 我们将利用以下内容:
Obviously we need Vue.js
as indicated in the tutorial title. vue-resource
which is an HTTP client for Vue.js making web requests and handled responses using XMLHttpRequest or JSONP. And lastly laravel-elixir-vueify
is a wrapper for Laravel Elixir and the Browserify Vueify plugin which allows you to write your templates
, scripts
and styles
all in one .vue
file. Install each of the dependencies using npm
. With the project dependencies installed, we can get to the meat of the project.
显然,如教程标题中所示,我们需要Vue.js
vue-resource
是Vue.js的HTTP客户端,它使用XMLHttpRequest或JSONP发出Web请求并处理响应。 最后, laravel-elixir-vueify
是Laravel Elixir和Browserify Vueify插件的包装,它允许您将templates
, scripts
和styles
全部写在一个.vue
文件中。 使用npm
安装每个依赖项。 安装了项目依赖项之后,我们就可以了解项目的实质了。
路线 ( The Routes )
Open routes.php
and paste the code below into it
打开routes.php
并将下面的代码粘贴到其中
// routes.php
Route::post('create-post', 'PostsController@save');
职位控制器 ( Posts Controller )
Create a PostsController
that will handle the logic for our post creation demo.
创建一个PostsController
,它将处理我们的后期创建演示的逻辑。
php artisan make:controller PostsController
Add a save()
to the PostsController
将save()
添加到PostsController
// PostsController.php
public function save(Request $request)
{
// set form validation rules
$this->validate($request, [
'title' => 'required',
'body' => 'required'
]);
// if the validation passes, save to database and redirect
}
The save()
handles post creation form validation.
save()
处理创建后的表单验证。
For the purpose of the tutorial, I'm keeping the validation simple by only making both the title
and body
fields required.
就本教程而言,我仅通过使title
字段和body
字段都必需来简化验证。
帖子查看 ( Post View )
Create a new file inside the views
directory and name it post.blade.php
. Paste the code below in it.
在views
目录中创建一个新文件,并将其命名为post.blade.php
。 将下面的代码粘贴到其中。
<!DOCTYPE html>
<html>
<head>
// add csrf token
<meta id="token" name="token" value="{{ csrf_token() }}">
<title>Handling Laravel Validation Error Messages With Vue.js</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
<style>
body {
padding: 50px;
}
</style>
</head>
<body>
<div class="container">
// this will be displayed upon successful submission of form
<div class="alert alert-success" v-if="submitted">
Post created!
</div>
// prevent the page from refreshing after submission
<form @submit.prevent="createPost" method="POST">
<legend>Create Post</legend>
// add Bootstrap .has-error if title field has errors
<div class="form-group@{{ errors.title ? ' has-error' : '' }}">
<label>Post Title</label>
<input type="text" name="title" class="form-control" v-model="post.title" value="{{ old('title') }}">
// display errors if field has errors using FormError component
<form-error v-if="errors.title" :errors="errors">
@{{ errors.title }}
</form-error>
</div>
// add Bootstrap .has-error if body field has errors
<div class="form-group@{{ errors.body ? ' has-error' : '' }}">
<label>Post Body</label>
<textarea name="body" class="form-control" rows="5" v-model="post.body">{{ old('body') }}</textarea>
// display errors if field has errors using FormError component
<form-error v-if="errors.body" :errors="errors">
@{{ errors.body }}
</form-error>
</div>
<button type="submit" class="btn btn-primary">Create Post</button>
</form>
</div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
You should have a form similar to the image below:
您应该具有类似于下图的表单:
Again, a simple form. There is a success message that will be displayed upon submission of the form using v-if
.
再次,一个简单的形式。 使用v-if
提交表单后,将会显示一条成功消息。
Since we want the form to be submitted asynchronously (without page refresh), @submit.prevent
will prevent the page from refreshing after submission.
由于我们希望表单异步提交(不刷新页面),因此@submit.prevent
将阻止页面在提交后刷新。
The form input data will be POST
ed to a createPost
function which we are yet to create. As you can see, I'm doing {{ errors.title ? ' has-error' : '' }}
which will add Bootstrap .has-error
if the title
field has errors. Same applies to the body
field.
表单输入数据将被POST
到我们尚未创建的createPost
函数。 如您所见,我正在做{{ errors.title ? ' has-error' : '' }}
{{ errors.title ? ' has-error' : '' }}
,如果title
字段有错误,它将添加Bootstrap .has-error
。 同样适用于body
领域。
To display the error messages when validation fails, I'm using the FormError
component (which we are yet to create) and passing to it errors
(which contains error messages) as props.
为了在验证失败时显示错误消息,我使用FormError
组件(我们尚未创建),并将errors
(包含错误消息)传递给它作为道具。
Vue.js文件 ( Vue.js File )
Create a new js
folder inside resources/assests
directory. Inside the newly created js
folder, create an app.js
file. Before going further, open the gulpfile.js
file and update it with:
在resources/assests
目录中创建一个新的js
文件夹。 在新创建的js
文件夹中,创建一个app.js
文件。 在继续之前,请打开gulpfile.js
文件并使用gulpfile.js
命令进行更新:
// gulpfile.js
var elixir = require('laravel-elixir');
require('laravel-elixir-vueify');
elixir(function(mix) {
mix.browserify('app.js');
});
Notice above, where we require laravel-elixir-vueify
, which will compile our .vue
file when we run gulp
.
注意上面,我们需要laravel-elixir-vueify
,这将编译我们.vue
当我们运行文件gulp
。
In the resources/assests/js/app.js
file, paste the code below into it.
在resources/assests/js/app.js
文件中,将以下代码粘贴到其中。
// resources/assests/js/app.js
import Vue from 'vue';
import VueResource from 'vue-resource';
// tell Vue to use the vue-resource plugin
Vue.use(VueResource);
// import FormError component
import FormError from './components/FormError.vue';
// get csrf token
Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('value');
// instantiate a new Vue instance
new Vue({
// mount Vue to .container
el: '.container',
// define components
components: {
FormError,
},
data: {
post: {
title: '',
body: '',
},
submitted: false,
// array to hold form errors
errors: [],
},
methods: {
createPost() {
let post = this.post;
this.$http.post('create-post', post).then(function(response) {
// form submission successful, reset post data and set submitted to true
this.post = {
title: '',
body: '',
};
// clear previous form errors
this.$set('errors', '');
this.submitted = true;
}, function (response) {
// form submission failed, pass form errors to errors array
this.$set('errors', response.data);
});
}
}
});
First, we import the packages (vue.js and vue-resource) installed earlier and tell Vue.js to use the vue-resource
plugin. Also, we import FormError
component which we'll create shortly.
首先,我们导入之前安装的软件包(vue.js和vue-resource),并告诉Vue.js使用vue-resource
插件。 另外,我们将导入FormError
组件,该组件将很快创建。
Next we create a Vue
instance and pass it an options object. The el
tells Vue.js
the element to mount on. The components
object accepts any components (FormError
in our case) we want included in our Vue
instance. The data
object contain data that can be rendered in a view. The post object contains a title and body object. It will hold the created post and will be binded to the post creation input fields. The submitted
defaults to false will be used to show the success message upon submission of form. The errors
array will obviously hold the errors messages returned during form validation. Finally the methods
object contains a single createPost()
.
接下来,我们创建一个Vue
实例并将其传递给options对象。 el
告诉Vue.js
要安装的元素。 components
对象接受我们要包含在Vue
实例中的所有组件(在我们的情况下为FormError
)。 data
对象包含可以在视图中呈现的数据。 发布对象包含标题和正文对象。 它将保存创建的帖子,并将其绑定到帖子创建输入字段。 submitted
默认值为false将用于在提交表单时显示成功消息。 errors
数组显然将保存在表单验证期间返回的错误消息。 最后, methods
对象包含一个createPost()
。
Taking a closer look at the createPost()
, first we declare a variable post
to hold the post data (submitted form data since we have two-way binding). Next, we send a post request to the route create-post
using the post()
of vue-resource plugin passing along the post variable (which now holds the submitted form data). If the request was successful, we set the form input value to empty string and set submitted
to true to show the success message. But if the request was not successful (that is the form validation failed), we set the errors
array to hold the form validation error messages Laravel sends upon failed validation.
仔细研究一下createPost()
,首先我们声明一个变量post
来保存post数据(由于我们具有双向绑定,因此提交了表单数据)。 接下来,我们使用vue-resource插件的post()
将post请求发送到路由create-post
,同时传递post变量(现在保存已提交的表单数据)。 如果请求成功,我们将表单输入值设置为空字符串,并将submitted
设置为true以显示成功消息。 但是,如果请求不成功(即表单验证失败),我们将设置errors
数组以容纳Laravel在验证失败时发送的表单验证错误消息。
FormError组件 ( FormError Component )
The FormError
component is going to be a very simple component. Create a new components
folder in resources/assests/js
and create a new file FormError.vue
inside the newly created components
folder. Paste the snippets below into it
FormError
组件将是一个非常简单的组件。 在resources/assests/js
创建一个新的components
文件夹,并在新创建的components
文件夹中创建一个新文件FormError.vue
。 将下面的代码片段粘贴到其中
<template>
<span class="help-block">
// this will be replaced by the error messages
<slot></slot>
</span>
</template>
<script>
export default {
props: ['errors'],
}
</script>
The template is a simple Bootstrap help block. The <slot>
tag will allow us to pass dynamic content into the template. In our case the <slot>
will be replaced by the error messages. Since the form validation error messages are unique to each form field, having the template show a specific error message for each field makes sense. The FormError
component accepts a props
errors
which must be passed along to the template.
该模板是一个简单的Bootstrap帮助块。 <slot>
标签将允许我们将动态内容传递到模板中。 在我们的情况下, <slot>
将被错误消息替换。 由于表单验证错误消息对于每个表单字段都是唯一的,因此让模板为每个字段显示特定的错误消息是有意义的。 FormError
组件接受必须传递给模板的props
errors
。
Now if you submit the form without filling the appropriate fields, you will get something similar to the image below showing the error messages:
现在,如果您提交表单时没有填写适当的字段,您将获得类似于以下显示错误消息的图像:
But if you fill the form as appropriate, you should get something like below:
但是,如果您填写适当的表格,则应该得到如下内容:
结论 ( Conclusion )
That's it. I hope you find this tutorial useful. If you encounter any problems following this tutorial or have suggestions, kindly drop them in the comment below.
而已。 希望本教程对您有所帮助。 如果您在本教程之后遇到任何问题或有建议,请将它们放在下面的评论中。
翻译自: https://scotch.io/tutorials/handling-laravel-validation-error-messages-with-vue-js