在初學習Laravel的過程中,看過的教程肯定都有登陸這個表單提交操作,當提交錯誤的時候,系統會返回$errors,而我們可以根據$errors來顯示在input框下面。
但是,在寫vuejs的時候,我就感覺自己比較的混亂,就是直接判斷status,如果不為1,則提取傳送的json資料中的msg,也就是自己定義的msg。
這幾天在看Laracast的Vue2教程中的Object-Oriented Forms給了我這個初學者很好的一個解答。
create.blade.php
<form method="POST" action="/projects" @submit.prevent="onSubmit" @keydown="form.errors.clear($event.target.name)">
<div class="field">
<label class="label">Name</label>
<div class="control">
<input class="input" type="text" name="name" placeholder="input name" v-model="form.name">
<span class="help is-danger" v-if="form.errors.has('name')" v-text="form.errors.get('name')"></span>
</div>
</div>
<div class="field">
<label class="label">Description</label>
<div class="control">
<input class="input" type="text" name="description" v-model="form.description" placeholder="input Description">
<span class="help is-danger" v-if="form.errors.has('description')" v-text="form.errors.get('description')"></span>
</div>
</div>
<div class="control">
<button class="button is-primary" :disabled="form.errors.any()">Save</button>
</div>
</form>
在這裡面,介紹幾個重點
- @submit.prevent="onSubmit"呼叫,我們阻止了表單提交,呼叫了我們自有的onSubmit函式。
- @keydown="form.errors.clear($event.target.name)",這個用於輸入時清空input框地下的錯誤提示
app.js
這邊分為3個部分,Vue的程式碼,Form Class,Errors Class
new Vue({
el: '#app',
data: {
form: new Form({
name: '',
description:'',
}),
},
methods: {
onSubmit() {
this.form.post("/projects")
.then(data => {
alert(data.message);
})
.catch(errors => {
console.log(errors);
});
},
}
});
我們通過onSubmit呼叫Form的post函式,可以直接將Form表單中的引數name和description傳送到"/projects"中
Form Class
class Form {
constructor(data) {
this.originalData = data;
for (let field in data) {
this[field] = data[field];
}
this.errors = new Errors();
}
data() {
let data = {};
for (let property in this.originalData) {
data[property] = this[property];
}
return data;
}
reset() {
for (let field in this.originalData)
{
this[field] = '';
}
this.errors.clear();
}
submit(requestType,url) {
return new Promise((resolve,reject) => {
axios[requestType](url,this.data())
.then(response => {
this.onSuccess(response.data);
resolve(response.data);
})
.catch(error => {
this.onFail(error.response.data.errors);
reject(error.response.data.errors);
});
});
}
onSuccess(data) {
this.reset();
}
onFail(errors) {
this.errors.record(errors)
}
post(url) {
return this.submit('post',url);
}
}
constructor為初始化函式,其中this.originalData用於遍歷訪問field(即name,description).通過for迴圈賦值,我們可以知道form裡面的資料就變成了以下這種情況
this.name = data.name
this.description = data.description
data函式為返回form表單中的資料,data[property] = this[property];其實就是上面這個的反向。
reset函式清空數值,當釋出成功後,清空input數值。
submit函式用於提交表單,Promise用來傳遞非同步操作的訊息,具體是為了讓我們form.post函式能繼續呼叫.then和.catch.
Errors Class
class Errors {
constructor() {
this.errors = {};
}
get(field) {
if (this.errors[field])
{
return this.errors[field][0];
}
}
has(field) {
return this.errors.hasOwnProperty(field);
}
any() {
return Object.keys(this.errors).length > 0;
}
record(errors) {
this.errors = errors;
}
clear(field) {
if (field) {
delete this.errors[field];
return;
}
this.errors = {};
}
}
errors類通過record將form提交返回的錯誤資訊存入其中,這樣我們就可以通過操作這個類,輕鬆的訪問到錯誤資訊。