外观
Form 表单
约 3172 字大约 11 分钟
2025-10-31
此组件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单校验等。
基础用法
<template>
<un-form :model="formData">
<un-form-item label="姓名" prop="name">
<un-input v-model="formData['name']" placeholder="请输入姓名" border="none"></un-input>
</un-form-item>
<un-form-item label="性别" prop="sex">
<un-radio-group v-model="formData['sex']" placeholder="请选择性别">
<un-radio name="男">男</un-radio>
<un-radio name="女">女</un-radio>
</un-radio-group>
</un-form-item>
<un-form-item label="爱好" prop="hobby">
<un-checkbox-group v-model="formData['hobby']" placeholder="请选择爱好">
<un-checkbox name="足球">足球</un-checkbox>
<un-checkbox name="篮球">篮球</un-checkbox>
<un-checkbox name="跑步">跑步</un-checkbox>
<un-checkbox name="游泳">游泳</un-checkbox>
</un-checkbox-group>
</un-form-item>
</un-form>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
const formData = reactive({
name: '',
sex: '男',
hobby: []
})
</script>注意
model 属性的数据类型是 UTSJSONObject 中响应式数据的绑定,需要使用 reactive 函数创建。
- 不能使用点语法,只能使用方括号语法。v-model="formData.name" 这种使用是错误的
- 不支持多级嵌套的响应式数据绑定。v-model="formData.userInfo.name" 这种使用是错误的
表单重置
表单重置功能可以将表单数据恢复到初始状态,并清除校验错误信息
un-form 组件提供了两种重置方式:
- 手动重置:直接操作数据对象,适用于无校验的表单
- 组件方法重置:使用组件提供的
resetFields方法,适用于带校验的表单
下面是组件方法重置的示例:
<template>
<un-form :model="formData" ref="formRef">
<un-form-item label="姓名" prop="name">
<un-input v-model="formData['name']" placeholder="请输入姓名" border="none"></un-input>
</un-form-item>
<un-form-item label="性别" prop="sex">
<un-radio-group v-model="formData['sex']" placeholder="请选择性别">
<un-radio name="男">男</un-radio>
<un-radio name="女">女</un-radio>
</un-radio-group>
</un-form-item>
<un-form-item label="爱好" prop="hobby">
<un-checkbox-group v-model="formData['hobby']" placeholder="请选择爱好">
<un-checkbox name="足球">足球</un-checkbox>
<un-checkbox name="篮球">篮球</un-checkbox>
<un-checkbox name="跑步">跑步</un-checkbox>
<un-checkbox name="游泳">游泳</un-checkbox>
</un-checkbox-group>
</un-form-item>
</un-form>
<un-button type="primary" text="提交" @click="submit"></un-button>
<un-button type="error" text="重置" @click="reset"></un-button>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
const formRef = ref<UnFormComponentPublicInstance | null>(null);
let formData = reactive({
name: '',
sex: '男',
hobby: []
})
const submit = () => {
console.log(formData)
}
const reset = () => {
formRef.value?.resetFields()
}
</script>表单校验
表单校验是确保用户输入数据符合预期格式和要求的重要功能。通过设置校验规则,可以在用户提交表单前自动检查数据的合法性,并提供友好的错误提示。
un-form 组件内置了表单校验功能,支持同步和异步校验,可以通过以下步骤实现:
- 在
un-form组件上绑定rules属性,定义校验规则 - 在
un-form-item组件上设置prop属性,对应校验规则中的字段名 - 通过
ref获取表单实例,调用校验方法
注意
校验规则的数据类型是 UTSJSONObject,获取校验规则的时候,使用了UTSJSONObject.keys()方法。再测试中发现,UTSJSONObject.keys()方法返回的属性名称的顺序,在不同平台上顺序不一致。
- 在 H5 平台上,是按照书写顺序返回的,和
Object.keys()方法返回的顺序一致 - 在 Android 平台上,没有按照书写顺序返回,暂时不清楚其顺序规则
这就导致了在 Android 平台上,校验错误提示的顺序和书写的不一致,暂时无法解决,只能等待uniapp官方后续版本修复
下面是一个完整的表单校验示例:
<template>
<un-form :model="formData" ref="formRef" :rules="formRules">
<un-form-item label="姓名" prop="name">
<un-input v-model="formData['name']" placeholder="请输入姓名" border="none"></un-input>
</un-form-item>
<un-form-item label="性别" prop="sex">
<un-radio-group v-model="formData['sex']" placeholder="请选择性别">
<un-radio name="男">男</un-radio>
<un-radio name="女">女</un-radio>
</un-radio-group>
</un-form-item>
<un-form-item label="爱好" prop="hobby">
<un-checkbox-group v-model="formData['hobby']" placeholder="请选择爱好">
<un-checkbox name="足球">足球</un-checkbox>
<un-checkbox name="篮球">篮球</un-checkbox>
<un-checkbox name="跑步">跑步</un-checkbox>
<un-checkbox name="游泳">游泳</un-checkbox>
</un-checkbox-group>
</un-form-item>
</un-form>
<un-button type="primary" text="提交" @click="submit"></un-button>
<un-button type="error" text="重置" @click="reset"></un-button>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import type { UnValidateResult } from '@/uni_modules/uview-unix';
const formRef = ref<UnFormComponentPublicInstance | null>(null);
let formData = reactive({
name: '',
sex: '男',
hobby: []
})
const formRules = {
//多个校验规则可以写在数组中
name: [
{
type: 'string',
required: true,
message: '请输入姓名',
trigger: ['blur', 'change']
}
],
sex: {
type: 'string',
required: true,
message: '请选择性别',
trigger: ['blur', 'change']
},
age: {
type: 'string',
required: true,
message: '请输入年龄',
trigger: ['blur', 'change']
}
};
const submit = () => {
formRef.value?.validate().then((result: UnValidateResult) => {
if(result.valid == true){
console.log('提交表单数据:', formData);
uni.showToast({
title: '提交成功',
icon: 'success'
});
}else{
uni.showToast({
title: result.errors[0].message,
icon: 'none'
});
}
})
}
const reset = () => {
formRef.value?.resetFields()
}
</script>校验规则
un-form 组件的校验规则支持丰富的参数配置,下表详细说明了各个参数的用法:
| 参数名 | 说明 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
trigger | 触发校验的方式,可同时监听:['change', 'blur'] | String/Array | 否 | Enum |
type | 内置校验规则类型,详见下方类型说明表 | String | 否 | 'string' |
required | 是否为必填字段,注意:此参数不会显示星号,需配置un-form-item的required属性 | Boolean | 否 | false |
pattern | 自定义正则表达式校验规则,如:/\d+/,不能带引号 | RegExp | 否 | - |
min | 最小值限制,字符串/数组比较长度,数值直接比较 | Number | 否 | - |
max | 最大值限制,规则同min | Number | 否 | - |
len | 精确长度,优先级高于min和max | Number | 否 | - |
message | 校验不通过时的提示信息 | String | 否 | - |
same | 校验两次输入是否一致,值为目标字段名 | String | 否 | - |
validator | 自定义校验函数 | Function | 否 | - |
内置校验规则类型 (type 参数)
| 类型值 | 说明 |
|---|---|
string | 必须是字符串类型(默认) |
number | 必须是数字类型 |
integer | 必须是整数类型 |
boolean | 必须是布尔类型 |
method | 必须是函数类型 |
regexp | 必须是正则表达式对象 |
array | 必须是数组类型 |
object | 必须是对象类型 |
phone | 必须是手机号格式 |
password | 必须是密码格式, 必须包含大小写字母、数字和特殊字符, 长度至少8个字符 |
idcard | 必须是身份证号格式 |
ip | 必须是IP地址格式,只支持IPv4 |
url | 必须是URL格式 |
hex | 必须是16进制格式 |
email | 必须是邮箱格式 |
any | 任意类型 |
same校验用法
same 校验规则用于校验两次输入是否一致,值为目标字段名。
const rules = {
password: [
{ required: true, message: '请输入密码' },
{ type: 'password', message: '密码格式不正确' }
],
confirmPassword: [
{ required: true, message: '请确认密码' },
{ same: 'password', message: '两次输入的密码不一致' }
]
};自定义校验函数参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
rule | Object | 当前校验字段在 rules 中所对应的校验规则对象 |
value | Any | 当前校验字段的值 |
callback | Function | 校验完成时的回调函数 |
自定义校验函数使用方法
自定义校验函数支持同步校验和异步校验。
同步校验:
- 返回
true表示校验通过 - 返回
false表示校验失败
异步校验:
- 校验通过:
callback(null) - 校验不通过:
callback('提示错误信息')
const formRules = {
name: [
{
type: 'string',
required: true,
message: '请填写姓名',
trigger: ['blur', 'change'],
},
{
// 此为同步验证
validator: (rule: any, value: any, callback: (message?: string) => void) => {
if (value.length > 5) {
return false //返回false,验证不通过
}
return true //返回true,验证通过
},
message: '名字不能大于5个字符',
trigger: ['change', 'blur'],
},
{
trigger: ['change', 'blur'],
validator: (rule: any, value: string, callback: (message?: string) => void) => {
setTimeout(() => {
if (!/^[\u4e00-\u9fa5]+$/.test(value)) {
callback('姓名必须为中文');
}
callback(null)
}, 200)
},
},
]
};通过合理组合这些校验参数,可以实现复杂而精确的表单校验逻辑,确保用户输入的数据符合业务需求。
校验错误提示方式
我们提供了多种校验的错误提示方式,传递给Form组件的errorType参数:
message:默认为输入框下方用文字进行提示none:不会进行任何提示border-bottom:配置作用域底部的下划线显示为红色,要求给form-item设置了borderBottom=true才有效toast:以"toast"提示的方式弹出错误信息,每次只弹出最前面的那个表单域的错误信息
<template>
<un-form errorType="message">
......
</un-form>
</template>API
Form Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| model | 表单数据对象 | UTSJSONObject | - |
| rules | 表单校验规则 | UTSJSONObject | - |
| errorType | 错误的提示方式,见上方说明 | Enum | message |
| borderBottom | 是否显示表单域的下划线边框 | Boolean | true |
| labelPosition | 表单域提示文字的位置,left-左侧,top-上方 | Enum | left |
| labelWidth | 提示文字的宽度,单位px | String | Number | 45 |
| labelAlign | lable字体的对齐方式 | Enum | left |
| labelVAlign | lable字体的垂直对齐方式 | Enum | middle |
| asteriskPosition | 必填星号的位置 | Enum | left |
| labelStyle | lable的样式,对象形式 | UTSJSONObject | string | - |
Form Methods
此方法如要通过ref手动调用
| 名称 | 说明 | 类型 |
|---|---|---|
| validate | 对整个表单进行校验的方法 | Function |
| validateField | 对部分表单字段进行校验 | Function |
| resetFields | 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 | Function |
Form-item Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| label | 左侧提示文字 | string | - |
| prop | 表单域model对象的属性名,在使用 validate、resetFields 方法的情况下,该属性是必填的 | string | - |
| rules | 表单校验规则 | UTSJSONObject | - |
| borderBottom | 是否显示下边框,如不需要下边框,需同时将un-form的同名参数设置为false | Boolean | true |
| labelWidth | 提示文字的宽度,单位rpx,如设置,将覆盖un-form的同名参数 | String | Number | - |
| labelPosition | label的位置 | Enum | - |
| labelAlign | lable字体的对齐方式 | Enum | left |
| labelVAlign | lable字体的垂直对齐方式 | Enum | middle |
| asteriskPosition | 必填星号的位置 | Enum | left |
| rightIcon | 右侧自定义字体图标(限uView内置图标)或图片地址 | string | - |
| leftIcon | 左侧自定义字体图标(限uView内置图标)或图片地址 | string | - |
| leftIconStyle | 左侧自定义字体图标的样式 | String | Object | - |
| required | 是否显示左边的"*"号,这里仅起展示作用,如需校验必填,请通过rules配置必填规则 | Boolean | false |
Form-item Slot
| 名称 | 说明 |
|---|---|
| default | Form Item 的内容 |
| right | 右侧自定义内容,可以在此传入一个按钮,用于获取校验码等场景 |
| error | 自定义传入校验错误时显示的信息,通过作用域插槽暴露了内部当前message错误信息 |
Form-item Events
| 事件名 | 说明 | 类型 |
|---|---|---|
| click | 点击时触发 | Function |
数据类型
/**
* 校验错误信息类型
* 用于表示单个字段的校验错误
*/
type UnValidateError = {
field: string; // 字段名
message: string; // 错误消息
}
/**
* 表单校验结果类型
* 用于表示整个表单的校验结果
*/
type UnValidateResult = {
valid: boolean; // 校验是否通过
errors: UnValidateError[]; // 错误信息列表
}Scss 变量
| 变量名 | 默认值 | 说明 |
|---|---|---|
| $un-form-item-body-min-height | 48px | 表单项最小高度 |
| $un-form-item-body-left-padding-right | 5px | 左侧内边距 |
| $un-form-item-body-left-required-margin-right | 2px | 必填项右边距 |
| $un-form-item-body-left-required-margin-left | 2px | 必填项左边距 |
| $un-form-item-body-left-icon-margin-right | 4px | 左侧图标右边距 |
| $un-form-item-body-left-required-color | $color-error | 必填项颜色 |
| $un-form-item-body-left-required-line-height | 20px | 必填项行高 |
| $un-form-item-body-left-required-font-size | 20px | 必填项字体大小 |
| $un-form-item-body-left-label-color | $text-color | 标签颜色 |
| $un-form-item-body-left-label-font-size | $text-base | 标签字体大小 |
| $un-form-item-body-right-icon-margin-left | 5px | 右侧图标左边距 |
| $un-form-item-top-margin | 10px 0 | 顶部外边距 |
| $un-form-item-top-left-margin-bottom | 10px | 顶部左侧下边距 |
| $un-form-item-line-bg-color | $border-color | 线条背景颜色 |
| $un-form-item-line-height | 1px | 线条高度 |
| $un-form-item-message-font-size | $text-sm | 消息字体大小 |
| $un-form-item-message-line-height | $line-sm | 消息行高 |
| $un-form-item-message-color | $color-error | 消息颜色 |
| $un-form-item-message-margin-bottom | 6px | 消息下边距 |
| $un-form-item-message-margin-top | -6px | 消息上边距 |
提示
组件内部默认使用 scss 变量,如需修改,请查看 scss 变量使用 文档
