Form 表单
17:06说明
表单校验容器,配合任意输入类组件使用。ux-form 负责收集表单内的 ux-form-item,向下提供 model / rules / error-type / label-* / size 等配置,并对外暴露 validate()、resetFields()、setRules();ux-form-item 是单个表单项,用 prop 关联 model 中的字段(支持 a.b 嵌套路径),负责渲染 label、必填星号、左右图标与错误提示,并在字段 blur / change 时按规则里的 trigger 触发校验。两者通过 provide/inject 协作,表单项内可放 ux-input、ux-textarea、ux-radio-group、ux-checkbox-group、ux-picker 等任意输入组件。
兼容性
| 平台 | 支持情况 |
|---|---|
| App | ✅ 支持 |
| H5 | ✅ 支持 |
| 微信小程序 | ✅ 支持 |
示例
基础用法
通过 rules 配置校验规则,validate() 校验全部字段,resetFields() 重置表单。
查看源码
vue
<template>
<ux-form ref="formRef" :model="model" :rules="rules" :error-type="['message']" label-position="left">
<ux-form-item label="姓名" prop="name" required left-icon="account">
<ux-input v-model="model.name" placeholder="请输入姓名" border />
</ux-form-item>
<ux-form-item label="密码" prop="password">
<ux-input v-model="model.password" type="password" :password-icon="true" placeholder="请输入密码" border />
</ux-form-item>
<ux-form-item label="手机号" prop="phone">
<ux-input v-model="model.phone" type="number" placeholder="请输入手机号" border />
</ux-form-item>
<ux-form-item label="性别" prop="sex">
<ux-input v-model="model.sex" type="select" :select-open="pickerShow" placeholder="请选择性别" border @click="pickerShow = true" />
</ux-form-item>
</ux-form>
<ux-button type="primary" @click="onSubmit">提交</ux-button>
<ux-button type="default" @click="onReset">重置</ux-button>
<ux-picker v-model="pickerShow" mode="selector" :columns="columns" @confirm="onConfirm" />
</template>
<script setup lang="uts">
import type { FormRule } from '@/uni_modules/uview-pro-x';
import type { PickerOption } from '@/uni_modules/uview-pro-x';
const formRef = ref<any | null>(null);
const pickerShow = ref<boolean>(false);
const model = ref<UTSJSONObject>(new UTSJSONObject());
model.value['name'] = '';
model.value['password'] = '';
model.value['phone'] = '';
model.value['sex'] = '';
const rules = ref<Map<string, FormRule[]>>(new Map([
['name', [
{ required: true, message: '请输入姓名', trigger: 'blur' },
{ min: 2, max: 5, message: '姓名长度在 2 到 5 个字符', trigger: 'change' }
]],
['password', [
{ required: true, message: '请输入密码', trigger: 'blur' }
]],
['phone', [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{
validator: (value: any | null): boolean | string => {
if (value == null || value === '') return true;
if (String(value).length !== 11) return '手机号码不正确';
return true;
},
trigger: 'change'
}
]],
['sex', [{ required: true, message: '请选择性别', trigger: 'change' }]]
]));
const columns: PickerOption[][] = [
[
{ text: '男', value: 'male' },
{ text: '女', value: 'female' }
]
];
const onSubmit = () => {
formRef.value?.validate().then((valid: boolean) => {
if (valid) {
uni.showToast({ title: '提交成功', icon: 'success' });
} else {
uni.showToast({ title: '校验失败', icon: 'none' });
}
});
};
const onReset = () => {
formRef.value?.resetFields();
};
const onConfirm = (event: UTSJSONObject): void => {
const options = event['selectedOptions'] as PickerOption[];
if (options != null && options.length > 0) {
model.value['sex'] = options[0].text;
}
};
</script>参数配置
查看源码
vue
<template>
<ux-form :model="model" :error-type="errorType" :label-position="labelPosition">
<ux-form-item label="错误提示方式" prop="name">
<ux-input v-model="model.name" placeholder="触发校验查看错误提示" border />
</ux-form-item>
</ux-form>
<view class="btn-wrap">
<ux-button size="small" :type="errorType[0] === 'message' ? 'primary' : 'default'" @click="setErrorType('message')">message</ux-button>
<ux-button size="small" :type="errorType[0] === 'toast' ? 'primary' : 'default'" @click="setErrorType('toast')">toast</ux-button>
<ux-button size="small" :type="labelPosition === 'top' ? 'primary' : 'default'" @click="labelPosition = 'top'">标签在上</ux-button>
<ux-button size="small" :type="labelPosition === 'left' ? 'primary' : 'default'" @click="labelPosition = 'left'">标签在左</ux-button>
</view>
</template>
<script setup lang="uts">
import type { FormErrorType } from '@/uni_modules/uview-pro-x';
const model = ref<UTSJSONObject>(new UTSJSONObject());
model.value['name'] = '';
const errorType = ref<FormErrorType[]>(['message']);
const labelPosition = ref<'left' | 'top'>('left');
const setErrorType = (value: string) => {
errorType.value = [value as FormErrorType];
};
</script>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-top: 10px;
}
</style>API
Props
ux-form
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
customStyle | 自定义根节点样式 | string | UTSJSONObject | - | - |
customClass | 自定义根节点样式类 | string | '' | - |
model | 表单数据对象 | UTSJSONObject | - | - |
rules | 表单验证规则 | FormRules | - | - |
errorType | 错误提示方式 | FormErrorType[] | - | - |
borderBottom | 是否显示下划线边框 | boolean | true | - |
labelPosition | label 位置 | FormLabelPosition | 'left' | - |
labelWidth | label 宽度 | string | number | 45 | - |
labelAlign | label 对齐方式 | string | 'left' | - |
labelStyle | label 样式 | UTSJSONObject | - | - |
size | 组件大小 | string | 'default' | - |
ux-form-item
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
customStyle | 自定义根节点样式 | string | UTSJSONObject | - | - |
customClass | 自定义根节点样式类 | string | '' | - |
label | input 的 label 提示语 | string | '' | - |
prop | 绑定的值 | string | '' | - |
borderBottom | 是否显示表单域的下划线边框 | string | boolean | '' | - |
labelPosition | label 的位置 | string | '' | - |
labelWidth | label 的宽度 | string | number | '' | - |
labelStyle | label 的样式 | UTSJSONObject | - | - |
labelAlign | label 字体的对齐方式 | string | '' | - |
rightIcon | 右侧图标 | string | '' | - |
leftIcon | 左侧图标 | string | '' | - |
leftIconPrefix | 左侧图标的自定义前缀 | string | 'uicon' | - |
rightIconPrefix | 右侧图标的自定义前缀 | string | 'uicon' | - |
leftIconStyle | 左侧图标的样式 | UTSJSONObject | - | - |
rightIconStyle | 右侧图标的样式 | UTSJSONObject | - | - |
required | 是否显示左边的必填星号 | boolean | false | - |
size | 表单内组件的大小 | string | '' | - |
Events
本页组件均无事件。
Slots
ux-form
| 插槽名 | 说明 | 版本 |
|---|---|---|
default | 表单内容,放置 ux-form-item | - |
ux-form-item
| 插槽名 | 说明 | 版本 |
|---|---|---|
leftIcon | 自定义左侧图标 | - |
label | 自定义 label 内容 | - |
default | 表单项内容,放置输入类组件(如 ux-input) | - |
rightIcon | 自定义右侧图标 | - |
right | 自定义右侧内容 | - |
方法
通过 ref 获取 ux-form 实例后调用:
| 方法名 | 说明 | 参数 | 返回值 |
|---|---|---|---|
validate | 校验全部已注册表单项,执行各字段的全部规则 | callback?: (valid: boolean, errorArr: ErrorItem[]) => void | Promise<boolean>,true 表示全部通过 |
resetFields | 重置全部表单项为初始值,并清除错误提示 | - | - |
setRules | 动态替换校验规则 | rules: FormRules | - |
注意事项
prop是校验与重置的前提:未设置prop的ux-form-item不会注册进表单,validate()与resetFields()都会跳过它;prop支持a.b嵌套路径。required只负责显示左侧红色星号,真正的必填校验必须在rules里配置required: true,两者互不替代。- 校验触发时机由规则的
trigger决定(blur/change):trigger: 'change'的规则不会在失焦时触发,反之亦然;整体调用validate()时会忽略trigger,执行该字段的全部规则。 error-type为数组,可同时开启多种提示(默认['message', 'toast']);数组里一旦包含none,所有提示(含 message / border)都会关闭。toast只弹出第一个出错字段的第一条错误。resetFields()把字段还原为组件挂载时记录的初始值(支持嵌套路径),而不是清空为''。ux-form-item的size/label-position/label-width/label-align/border-bottom未单独设置时,继承ux-form上的同名配置;border-bottom在ux-form上默认true。- label 传空字符串时,label 区域宽度自动为
auto(此时label-width不生效)。