使用基本数据绑定验证表单
表单是一种用于收集信息的文档。HTML 的 <form> 元素就是一个表单,可以从网页用户那里收集数据或信息。该元素需要包含 <input> 元素来指定我们要收集的数据。但在接收数据之前,我们通常需要验证和过滤这些数据,以确保从用户那里获取真实准确的信息。
Vue 让我们能够轻松地验证来自 v-model 输入元素的数据。让我们从创建一个单文件组件(SFC)的 Vue 应用和 webpack 开始(这些内容您在第 5 章《添加 Vue 组件》的 "使用 webpack 编译单文件组件" 一节中已经学过)。首先,我们将创建一个非常简单的表单,包含提交按钮和显示错误信息的标记,如下所示:
// src/components/basic.vue
<form v-on:submit.prevent="checkForm" action="/" method="post">
<p v-if="errors.length">
<b>请更正以下错误:</b>
<ul>
<li v-for="error in errors">{{ error }}</li>
</ul>
</p>
<p>
<input type="submit" value="Submit">
</p>
</form>
我们稍后会在 <form> 中添加其余的输入元素。现在,让我们先建立基本结构并理解我们需要什么。我们使用 v-on:submit.prevent 来阻止浏览器默认发送表单数据,因为我们将在 Vue 实例的 <script> 块中用 checkForm 方法处理提交:
// src/components/basic.vue
export default {
data () {
return {
errors: [],
form: {...}
}
},
methods: {
checkForm (e) {
this.errors = []
if (!this.errors.length) {
this.processForm(e)
}
},
processForm (e) {...}
}
}
在 JavaScript 部分,我们定义了一个数组来保存验证过程中可能出现的错误。checkForm 逻辑会验证我们稍后将在本节中添加的必填字段。如果必填字段未通过验证,我们会将错误信息推送到 errors 数组中。当表单填写正确且没有发现错误时,数据将被传递给 processForm 逻辑,在那里我们可以对表单数据进行进一步处理,然后再发送到服务器。
验证文本元素
让我们从添加一个单行文本的 <input> 元素开始:
// src/components/basic.vue
<label for="name">Name</label>
<input v-model="form.name" type="text">
export default {
data () {
return {
form: { name: null }
}
},
methods: {
checkForm (e) {
this.errors = []
if (!this.form.name) {
this.errors.push('Name required')
}
}
}
}
在 <script> 块中,我们在 data 函数中定义了一个 name 属性,初始值为 null,该值将通过 <input> 元素的 input 事件更新。当点击提交按钮时,我们会在 if 条件块中验证 name 数据;如果没有提供数据,则将错误信息推送到 errors 数组中。
验证 textarea 元素
接下来我们添加用于多行文本的 <textarea> 元素,其工作方式与 <input> 相同:
// src/components/basic.vue
<label for="message">Message</label>
<textarea v-model="form.message"></textarea>
export default {
data () {
return {
form: { message: null }
}
},
methods: {
checkForm (e) {
this.errors = []
if (!this.form.message) {
this.errors.push('Message required')
}
}
}
}
在 <script> 块中,我们在 data 函数中定义了一个 message 属性,初始值为 null,该值将通过 <textarea> 元素的 input 事件更新。当点击提交按钮时,我们会在 if 条件块中验证 message 数据;如果没有提供数据,则将错误信息推送到 errors 数组中。
验证复选框元素
下一个是单选框 <input> 元素,它将保存默认的布尔值:
// src/components/basic.vue
<label class="label">Subscribe</label>
<input type="checkbox" v-model="form.subscribe">
export default {
data () {
return {
form: { subscribe: false }
}
},
methods: {
checkForm (e) {
this.errors = []
if (!this.form.subscribe) {
this.errors.push('Subscription required')
}
}
}
}
我们还将添加以下多个复选框 <input> 元素,它们都绑定到同一个数组 books: []:
// src/components/basic.vue
<input type="checkbox" v-model="form.books" value="On the Origin of Species">
<label for="On the Origin of Species">On the Origin of Species</label>
<input type="checkbox" v-model="form.books" value="A Brief History of Time">
<label for="A Brief History of Time">A Brief History of Time</label>
<input type="checkbox" v-model="form.books" value="The Selfish Gene">
<label for="The Selfish Gene">The Selfish Gene</label>
export default {
data () {
return {
form: { books: [] }
}
},
methods: {
checkForm (e) {
this.errors = []
if (this.form.books.length === 0) {
this.errors.push('必须选择书籍')
}
}
}
}
在 <script> 块中,我们在 data 函数中定义了一个 subscribe 属性,初始值为布尔值 false,该值将通过复选框 <input> 元素的 change 事件更新。当点击提交按钮时,我们会在 if 条件块中验证 subscribe 数据;如果没有提供数据或其值为 false,则将错误信息推送到 errors 数组中。
我们对多个复选框 <input> 元素也做了同样的处理,定义了一个 books 属性,初始值为空数组,该值将通过复选框 <input> 元素的 change 事件更新。我们在 if 条件块中验证 books 数据;如果其长度为 0,则将错误信息推送到 errors 数组中。
验证单选框元素
接下来是多个单选按钮 <input> 元素,它们都绑定到同一个属性 gender:
// src/components/basic.vue
<label for="male">Male</label>
<input type="radio" v-model="form.gender" value="male">
<label for="female">Female</label>
<input type="radio" v-model="form.gender" value="female">
<label for="other">Other</label>
<input type="radio" v-model="form.gender" value="other">
export default {
data () {
return {
form: { gender: null }
}
},
methods: {
checkForm (e) {
this.errors = []
if (!this.form.gender) {
this.errors.push('Gender required')
}
}
}
}
在 <script> 块中,我们在 data 函数中定义了一个 gender 属性,初始值为 null,该值将通过所选单选按钮 <input> 元素的 change 事件更新。当点击提交按钮时,我们会在 if 条件块中验证 gender 数据;如果没有提供数据,则将错误信息推送到 errors 数组中。
验证 select 元素
下一个是包含多个 <option> 元素的单个 <select> 下拉框:
// src/components/basic.vue
<select v-model="form.favourite">
<option disabled value="">Please select one</option>
<option value="On the Origin of Species">On the Origin of Species</option>
<option value="A Brief History of Time">A Brief History of Time</option>
<option value="The Selfish Gene">The Selfish Gene</option>
</select>
export default {
data () {
return {
form: { favourite: null }
}
},
methods: {
checkForm (e) {
this.errors = []
if (!this.form.favourite) {
this.errors.push('Favourite required')
}
}
}
}
最后一个是多个 <select> 元素,其中包含多个 <option> 元素,它们绑定到同一个数组,即 favourites: []
// src/components/basic.vue
<select v-model="form.favourites" multiple>
<option value="On the Origin of Species">On the Origin of Species</option>
<option value="A Brief History of Time">A Brief History of Time</option>
<option value="The Selfish Gene">The Selfish Gene</option>
</select>
export default {
data () {
return {
form: { favourites: [] }
}
},
methods: {
checkForm (e) {
this.errors = []
if (this.form.favourites.length === 0) {
this.errors.push('Favourites required')
}
}
}
}
在 <script> 块中,我们在 data 函数定义了 favourite 属性(初始值为 null),其值将通过 <select> 元素的 change 事件更新。当点击提交按钮时,若未选择任何选项,则推送错误信息到 errors 数组。对于多选 <select> 元素,我们定义了 favourites 数组属性,若其长度为 0 则推送错误信息。
最后我们将在 checkForm 验证通过时调用 processForm 方法。使用 Node.js 的 qs 包将表单对象序列化为 name=John&message=Hello%20World&subscribe=true&gender=other 格式以便提交:
通过 npm 安装 qs:
$ npm i qs
使用示例:
import axios from 'axios'
import qs from 'qs'
processForm (e) {
var data = qs.stringify(this.form)
axios.post('../server.php', data)
.then((response) => {
// 成功回调
}, (response) => {
// 失败回调
})
}
我们使用 axios 发送数据,并从服务器获取响应(通常是 JSON 格式),然后你可以对响应数据执行某些操作,例如在服务器端显示“成功”或“失败”消息。
|
更多关于 完整示例代码可在 |
然而,我们还没有完全完成,因为有时我们可能希望将动态值绑定到表单输入,而不是从 v-model 获取默认值。例如,在我们的示例应用中,对于单个复选框 <input> 元素,我们只为 subscribe 属性获取布尔值,但我们希望使用字符串值 yes 或 no 来代替。我们将在下一节探讨如何更改默认值。