表单组件
表单组件是用户交互的重要部分,uni-app 提供了丰富的表单组件,用于采集和提交用户输入的数据。
表单组件列表
button 按钮
按钮组件,用于触发操作。
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
size | String | default | 按钮的大小,可选值:default、mini |
type | String | default | 按钮的样式类型,可选值:primary、default、warn |
plain | Boolean | false | 按钮是否镂空,背景色透明 |
disabled | Boolean | false | 是否禁用 |
loading | Boolean | false | 名称前是否带 loading 图标 |
form-type | String | 用于 form 组件,点击分别会触发 form 组件的 submit/reset 事件 | |
open-type | String | 开放能力,不同平台有不同的支持度 | |
hover-class | String | button-hover | 指定按钮按下去的样式类 |
示例代码
vue
<template>
<view>
<button type="primary">主要按钮</button>
<button type="default">默认按钮</button>
<button type="warn">警告按钮</button>
<button type="primary" loading>加载中按钮</button>
<button type="primary" disabled>禁用按钮</button>
<button type="primary" plain>镂空按钮</button>
</view>
</template>
checkbox 多选框
多选框组件,用于选择。
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
value | String | checkbox 标识 | |
disabled | Boolean | false | 是否禁用 |
checked | Boolean | false | 当前是否选中 |
color | Color | checkbox 的颜色 |
示例代码
vue
<template>
<view>
<checkbox-group @change="checkboxChange">
<label v-for="item in items" :key="item.value">
<checkbox :value="item.value" :checked="item.checked" />
{{item.name}}
</label>
</checkbox-group>
</view>
</template>
<script>
export default {
data() {
return {
items: [
{value: 'USA', name: '美国', checked: false},
{value: 'CHN', name: '中国', checked: true},
{value: 'JPN', name: '日本', checked: false}
]
}
},
methods: {
checkboxChange(e) {
console.log(e.detail.value)
}
}
}
</script>
input 输入框
输入框组件,用于文本输入。
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
value | String | 输入框的初始内容 | |
type | String | text | input 的类型,可选值:text、number、idcard、digit、password |
password | Boolean | false | 是否是密码类型 |
placeholder | String | 输入框为空时占位符 | |
placeholder-style | String | 指定 placeholder 的样式 | |
disabled | Boolean | false | 是否禁用 |
maxlength | Number | 140 | 最大输入长度 |
focus | Boolean | false | 获取焦点 |
confirm-type | String | done | 设置键盘右下角按钮的文字,可选值:send、search、next、go、done |
示例代码
vue
<template>
<view>
<input type="text" placeholder="请输入用户名" v-model="username" />
<input type="password" placeholder="请输入密码" v-model="password" />
<input type="number" placeholder="请输入年龄" v-model="age" />
</view>
</template>
<script>
export default {
data() {
return {
username: '',
password: '',
age: ''
}
}
}
</script>
picker 选择器
选择器组件,支持普通选择器、多列选择器、时间选择器、日期选择器。
普通选择器
vue
<template>
<view>
<picker :range="array" @change="bindPickerChange">
<view class="picker">
当前选择:{{array[index]}}
</view>
</picker>
</view>
</template>
<script>
export default {
data() {
return {
array: ['中国', '美国', '日本', '韩国'],
index: 0
}
},
methods: {
bindPickerChange(e) {
this.index = e.detail.value
}
}
}
</script>
时间选择器
vue
<template>
<view>
<picker mode="time" :value="time" start="09:00" end="18:00" @change="bindTimeChange">
<view class="picker">
当前选择:{{time}}
</view>
</picker>
</view>
</template>
<script>
export default {
data() {
return {
time: '12:00'
}
},
methods: {
bindTimeChange(e) {
this.time = e.detail.value
}
}
}
</script>
日期选择器
vue
<template>
<view>
<picker mode="date" :value="date" start="2015-09-01" end="2025-09-01" @change="bindDateChange">
<view class="picker">
当前选择:{{date}}
</view>
</picker>
</view>
</template>
<script>
export default {
data() {
return {
date: '2021-09-01'
}
},
methods: {
bindDateChange(e) {
this.date = e.detail.value
}
}
}
</script>
radio 单选框
单选框组件,用于单选。
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
value | String | radio 标识 | |
checked | Boolean | false | 当前是否选中 |
disabled | Boolean | false | 是否禁用 |
color | Color | radio 的颜色 |
示例代码
vue
<template>
<view>
<radio-group @change="radioChange">
<label v-for="item in items" :key="item.value">
<radio :value="item.value" :checked="item.checked" />
{{item.name}}
</label>
</radio-group>
</view>
</template>
<script>
export default {
data() {
return {
items: [
{value: 'USA', name: '美国', checked: false},
{value: 'CHN', name: '中国', checked: true},
{value: 'JPN', name: '日本', checked: false}
]
}
},
methods: {
radioChange(e) {
console.log(e.detail.value)
}
}
}
</script>
slider 滑动选择器
滑动选择器,用于选择一个数值。
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
min | Number | 0 | 最小值 |
max | Number | 100 | 最大值 |
step | Number | 1 | 步长,取值必须大于 0,并且可被(max - min)整除 |
disabled | Boolean | false | 是否禁用 |
value | Number | 0 | 当前取值 |
show-value | Boolean | false | 是否显示当前 value |
activeColor | Color | #1aad19 | 已选择的颜色 |
backgroundColor | Color | #e9e9e9 | 背景条的颜色 |
block-size | Number | 28 | 滑块的大小,取值范围为 12 - 28 |
block-color | Color | #ffffff | 滑块的颜色 |
示例代码
vue
<template>
<view>
<slider value="50" @change="sliderChange" show-value />
</view>
</template>
<script>
export default {
methods: {
sliderChange(e) {
console.log('slider value 发生变化:' + e.detail.value)
}
}
}
</script>
switch 开关选择器
开关选择器,用于切换选中状态。
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
checked | Boolean | false | 是否选中 |
disabled | Boolean | false | 是否禁用 |
type | String | switch | 样式,有效值:switch, checkbox |
color | Color | switch 的颜色 |
示例代码
vue
<template>
<view>
<switch checked @change="switchChange" />
<switch type="checkbox" />
</view>
</template>
<script>
export default {
methods: {
switchChange(e) {
console.log('switch 发生 change 事件,携带值为', e.detail.value)
}
}
}
</script>
textarea 多行输入框
多行输入框,用于多行文本输入。
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
value | String | 输入框的内容 | |
placeholder | String | 输入框为空时占位符 | |
placeholder-style | String | 指定 placeholder 的样式 | |
disabled | Boolean | false | 是否禁用 |
maxlength | Number | 140 | 最大输入长度 |
focus | Boolean | false | 获取焦点 |
auto-height | Boolean | false | 是否自动增高 |
fixed | Boolean | false | 如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true |
示例代码
vue
<template>
<view>
<textarea placeholder="请输入留言" v-model="message" auto-height />
</view>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
form 表单
表单容器,用于将表单组件内的用户输入的数据提交。
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
report-submit | Boolean | false | 是否返回 formId 用于发送模板消息 |
示例代码
vue
<template>
<view>
<form @submit="formSubmit" @reset="formReset">
<view class="form-item">
<text>姓名:</text>
<input name="name" placeholder="请输入姓名" />
</view>
<view class="form-item">
<text>年龄:</text>
<input name="age" placeholder="请输入年龄" />
</view>
<view class="form-buttons">
<button type="primary" form-type="submit">提交</button>
<button form-type="reset">重置</button>
</view>
</form>
</view>
</template>
<script>
export default {
methods: {
formSubmit(e) {
console.log('form发生了submit事件,携带数据为:', e.detail.value)
},
formReset(e) {
console.log('form发生了reset事件')
}
}
}
</script>
<style>
.form-item {
display: flex;
margin-bottom: 10px;
}
.form-buttons {
display: flex;
justify-content: space-around;
margin-top: 20px;
}
</style>
表单校验
在实际应用中,表单校验是非常重要的一环。uni-app 可以结合第三方表单校验库(如 async-validator)或自定义校验逻辑来实现表单校验。
使用 async-validator 进行表单校验
vue
<template>
<view class="container">
<form @submit="submitForm">
<view class="form-item">
<text class="label">用户名:</text>
<input v-model="formData.username" placeholder="请输入用户名" />
<text v-if="errors.username" class="error">{{errors.username[0]}}</text>
</view>
<view class="form-item">
<text class="label">邮箱:</text>
<input v-model="formData.email" placeholder="请输入邮箱" />
<text v-if="errors.email" class="error">{{errors.email[0]}}</text>
</view>
<view class="form-item">
<text class="label">年龄:</text>
<input v-model="formData.age" type="number" placeholder="请输入年龄" />
<text v-if="errors.age" class="error">{{errors.age[0]}}</text>
</view>
<button type="primary" form-type="submit">提交</button>
</form>
</view>
</template>
<script>
import Schema from 'async-validator';
export default {
data() {
return {
formData: {
username: '',
email: '',
age: ''
},
errors: {}
}
},
methods: {
submitForm() {
// 定义校验规则
const rules = {
username: [
{ required: true, message: '请输入用户名' },
{ min: 3, max: 20, message: '用户名长度在 3 到 20 个字符' }
],
email: [
{ required: true, message: '请输入邮箱' },
{ type: 'email', message: '请输入正确的邮箱格式' }
],
age: [
{ required: true, message: '请输入年龄' },
{ type: 'number', message: '年龄必须为数字' },
{ min: 18, max: 100, message: '年龄必须在 18 到 100 之间' }
]
};
// 创建校验器
const validator = new Schema(rules);
// 执行校验
validator.validate(this.formData, (errors, fields) => {
if (errors) {
// 校验失败,显示错误信息
this.errors = fields;
} else {
// 校验通过,清空错误信息
this.errors = {};
// 提交表单数据
uni.showToast({
title: '提交成功',
icon: 'success'
});
console.log('表单数据:', this.formData);
}
});
}
}
}
</script>
<style>
.container {
padding: 20px;
}
.form-item {
margin-bottom: 20px;
}
.label {
display: block;
margin-bottom: 5px;
}
.error {
color: #f00;
font-size: 12px;
margin-top: 5px;
}
</style>
最佳实践
- 表单数据统一管理:将表单数据统一放在 data 中管理,便于提交和校验。
- 合理使用双向绑定:使用 v-model 进行双向数据绑定,简化数据处理。
- 分组管理复杂表单:对于复杂表单,可以将其拆分为多个小组件,分别管理。
- 表单校验前端先行:在提交到服务器前,先在前端进行数据校验,减轻服务器压力。
- 友好的错误提示:提供清晰、具体的错误提示,帮助用户快速修正输入。
- 适配不同平台:注意表单组件在不同平台上的表现差异,做好兼容处理。
- 合理使用 placeholder:提供有意义的占位符文本,引导用户输入。
- 考虑无障碍设计:为表单元素添加适当的标签和描述,提高可访问性。
常见问题
1. 表单组件在不同平台上的差异
uni-app 的表单组件在不同平台上可能存在差异,特别是在样式和交互方面。建议在开发时多测试,确保在各平台上都有良好的表现。
2. 键盘遮挡输入框
在移动端,当用户点击输入框时,键盘弹出可能会遮挡输入框。可以通过调整页面布局或使用 adjust-position
属性来解决。
3. 表单数据的重置
使用 form 组件的 reset 事件可以方便地重置表单数据,但需要注意的是,这只会重置表单组件的值,不会重置绑定的数据模型。如果需要同时重置数据模型,需要在 reset 事件处理函数中手动重置。
4. 表单提交时的防重复提交
为了防止用户多次点击提交按钮导致重复提交,可以在提交时禁用提交按钮,等待服务器响应后再启用。
vue
<template>
<view>
<form @submit="submitForm">
<!-- 表单内容 -->
<button type="primary" form-type="submit" :disabled="submitting">
{{submitting ? '提交中...' : '提交'}}
</button>
</form>
</view>
</template>
<script>
export default {
data() {
return {
submitting: false
}
},
methods: {
submitForm() {
if (this.submitting) return;
this.submitting = true;
// 模拟提交请求
setTimeout(() => {
uni.showToast({
title: '提交成功',
icon: 'success'
});
this.submitting = false;
}, 2000);
}
}
}
</script>