Form 表单
表单容器组件,支持表单验证、字段管理、错误提示等功能。
基础表单
简单的表单验证示例。
html
<form class="sa-form" id="basicForm" style="max-width: 600px;" data-label-position="right" data-label-width="100px">
<div class="sa-form-item">
<label class="sa-form-item__label">用户名</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="username"
data-placeholder="请输入用户名"
data-clearable="true"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">邮箱</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="email"
data-placeholder="请输入邮箱"
data-type="email"
data-clearable="true"></div>
</div>
</div>
<div style="margin-top: 20px; display: flex; gap: 10px;">
<button type="submit" class="sa-button sa-button--primary">提交</button>
<button type="button" class="sa-button" id="resetBtn1">重置</button>
<button type="button" class="sa-button" id="validateBtn1">验证</button>
</div>
</form>
<script>
const basicForm = new SaForm('#basicForm', {
rules: {
username: [
{ required: true, message: '用户名不能为空' },
{ min: 3, max: 20, message: '用户名长度在 3 到 20 个字符' }
],
email: [
{ required: true, message: '邮箱不能为空' },
{ type: 'email', message: '请输入正确的邮箱格式' }
]
}
});
SA.init('body');
</script>加载 SanoUI 组件中...
完整验证规则
包含多种验证规则的表单,演示 required、min、max、type、pattern 和自定义 validator 等验证规则。
html
<form class="sa-form" id="fullForm" style="max-width: 600px;" data-label-position="right" data-label-width="100px">
<div class="sa-form-item">
<label class="sa-form-item__label">用户名</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="username"
data-placeholder="3-20个字符"
data-clearable="true"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">密码</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="password"
data-placeholder="至少6个字符"
data-type="password"
data-show-password="true"
data-clearable="false"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">确认密码</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="confirmPassword"
data-placeholder="再次输入密码"
data-type="password"
data-show-password="true"
data-clearable="false"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">邮箱</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="email"
data-placeholder="example@email.com"
data-type="email"
data-clearable="true"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">手机号</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="phone"
data-placeholder="11位手机号"
data-clearable="true"></div>
</div>
</div>
<div style="margin-top: 20px; display: flex; gap: 10px;">
<button type="submit" class="sa-button sa-button--primary">提交</button>
<button type="button" class="sa-button" id="resetBtn2">重置</button>
<button type="button" class="sa-button" id="clearValidateBtn">清除验证</button>
</div>
</form>
<script>
const fullForm = new SaForm('#fullForm', {
rules: {
username: [
{ required: true, message: '用户名不能为空' },
{ min: 3, max: 20, message: '用户名长度在 3 到 20 个字符' }
],
password: [
{ required: true, message: '密码不能为空' },
{ min: 6, message: '密码长度不能少于 6 个字符' }
],
confirmPassword: [
{ required: true, message: '请确认密码' },
{
validator: (rule, value, allValues) => {
if (value !== allValues.password) {
return '两次输入的密码不一致';
}
return true;
},
message: '两次输入的密码不一致'
}
],
email: [
{ required: true, message: '邮箱不能为空' },
{ type: 'email', message: '请输入正确的邮箱格式' }
],
phone: [
{ required: true, message: '手机号不能为空' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式' }
]
}
});
SA.init('body');
</script>加载 SanoUI 组件中...
不同布局
标签在上方
使用 data-label-position="top" 将标签放在上方。
html
<form class="sa-form" id="topForm" style="max-width: 600px;" data-label-position="top">
<div class="sa-form-item">
<label class="sa-form-item__label">用户名</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="username"
data-placeholder="请输入用户名"
data-clearable="true"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">邮箱</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="email"
data-placeholder="请输入邮箱"
data-type="email"
data-clearable="true"></div>
</div>
</div>
</form>
<script>
const topForm = new SaForm('#topForm');
SA.init('body');
</script>加载 SanoUI 组件中...
标签在左侧
使用 data-label-position="left" 和 data-label-width="100px" 将标签放在左侧。
html
<form class="sa-form" id="leftForm" style="max-width: 600px;" data-label-position="left" data-label-width="100px">
<div class="sa-form-item">
<label class="sa-form-item__label">用户名</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="username"
data-placeholder="请输入用户名"
data-clearable="true"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">邮箱</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="email"
data-placeholder="请输入邮箱"
data-type="email"
data-clearable="true"></div>
</div>
</div>
</form>
<script>
const leftForm = new SaForm('#leftForm');
SA.init('body');
</script>加载 SanoUI 组件中...
自动初始化
使用 SA.init() 可以自动初始化表单内的所有组件,包括 form、input、button 等。
html
<form class="sa-form" id="autoInitForm" style="max-width: 600px;" data-label-position="right" data-label-width="100px">
<div class="sa-form-item">
<label class="sa-form-item__label">用户名</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="username"
data-placeholder="请输入用户名"
data-value="admin"
data-clearable="true"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">密码</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="password"
data-placeholder="请输入密码"
data-type="password"
data-show-password="true"
data-clearable="false"></div>
</div>
</div>
<div style="margin-top: 20px; display: flex; gap: 10px;">
<button type="submit" class="sa-button sa-button--primary">提交</button>
<button type="button" class="sa-button" id="getValuesBtn">获取值</button>
</div>
</form>
<script>
// 使用 SA.init() 自动初始化所有组件
const page = SA.init('body');
// 手动创建表单实例并配置验证规则
const autoInitForm = new SaForm('#autoInitForm', {
rules: {
username: [
{ required: true, message: '用户名不能为空' }
],
password: [
{ required: true, message: '密码不能为空' },
{ min: 6, message: '密码长度不能少于 6 个字符' }
]
}
});
</script>加载 SanoUI 组件中...
API
构造函数
javascript
new SaForm(container, config)参数
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
container | 容器选择器或元素 | string | HTMLElement | - |
config | 配置选项 | SaFormOptions | {} |
配置选项
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
rules | 验证规则对象 | Object<string, Array<Rule>> | {} |
labelPosition | 标签位置 | 'left' | 'right' | 'top' | 'right' |
labelWidth | 标签宽度 | string | '100px' |
labelSuffix | 标签后缀 | string | '' |
inline | 是否行内表单 | boolean | false |
disabled | 是否禁用表单 | boolean | false |
size | 表单尺寸 | 'large' | 'default' | 'small' | 'default' |
showMessage | 是否显示错误消息 | boolean | true |
验证规则 (Rule)
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
required | 是否必填 | boolean | false |
message | 错误提示信息 | string | - |
min | 最小长度(字符串)或最小值(数字) | number | - |
max | 最大长度(字符串)或最大值(数字) | number | - |
type | 类型验证 | 'string' | 'number' | 'email' | 'url' | 'tel' | - |
pattern | 正则表达式验证 | RegExp | - |
validator | 自定义验证函数 | function(rule, value, allValues): boolean | string | - |
trigger | 触发验证的时机 | 'blur' | 'change' | 'blur' |
Data 属性
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
data-label-position | 标签位置 | string | 'right' |
data-label-width | 标签宽度 | string | '100px' |
data-label-suffix | 标签后缀 | string | '' |
data-inline | 是否行内表单 | boolean | false |
data-disabled | 是否禁用 | boolean | false |
data-size | 表单尺寸 | string | 'default' |
data-show-message | 是否显示错误消息 | boolean | true |
方法
| 方法名 | 说明 | 参数 | 返回值 |
|---|---|---|---|
registerField(prop, element, rules?) | 注册表单字段 | prop: string - 字段属性名element: HTMLElement - 字段元素rules?: Array<Rule> - 验证规则 | this |
validate(props?) | 验证表单 | props?: Array<string> - 要验证的字段列表 | Promise<Object> - 验证通过返回表单数据,失败返回错误对象 |
validateField(prop) | 验证单个字段 | prop: string - 字段属性名 | Promise<boolean> |
getFieldsValue(props?) | 获取表单数据 | props?: Array<string> - 要获取的字段列表 | Object - 表单数据对象 |
setFieldsValue(values) | 设置表单字段值 | values: Object - 字段值对象 { prop: value } | void |
resetFields(props?) | 重置表单字段 | props?: Array<string> - 要重置的字段列表 | this |
clearValidate(props?) | 清除字段验证错误 | props?: string | Array<string> - 字段属性名或数组 | this |
destroy() | 销毁实例 | - | void |
字段注册
表单字段需要通过 data-prop 属性注册:
html
<div class="sa-input" data-prop="username"></div>或手动注册:
javascript
form.registerField('username', element, [
{ required: true, message: '用户名不能为空' }
]);实际使用场景
场景 1:用户注册表单
完整的用户注册表单,包含用户名、密码、确认密码、邮箱等字段的验证。
html
<form class="sa-form" id="register-form" style="max-width: 500px;" data-label-position="right" data-label-width="120px">
<div class="sa-form-item">
<label class="sa-form-item__label">用户名</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="username"
data-placeholder="3-20个字符,支持字母、数字、下划线"
data-clearable="true"
style="width: 100%;"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">密码</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="password"
data-placeholder="至少6个字符"
data-type="password"
data-show-password="true"
style="width: 100%;"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">确认密码</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="confirmPassword"
data-placeholder="再次输入密码"
data-type="password"
data-show-password="true"
style="width: 100%;"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">邮箱</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="email"
data-placeholder="example@email.com"
data-type="email"
data-clearable="true"
style="width: 100%;"></div>
</div>
</div>
<div style="margin-top: 20px; display: flex; gap: 10px;">
<button type="submit" class="sa-button sa-button--primary">注册</button>
<button type="button" class="sa-button" onclick="resetRegisterForm()">重置</button>
</div>
</form>
<script>
SA.init('body');
const registerForm = new SaForm('#register-form', {
rules: {
username: [
{ required: true, message: '用户名不能为空' },
{ min: 3, max: 20, message: '用户名长度在 3 到 20 个字符' },
{ pattern: /^[a-zA-Z0-9_]+$/, message: '用户名只能包含字母、数字和下划线' }
],
password: [
{ required: true, message: '密码不能为空' },
{ min: 6, message: '密码长度不能少于 6 个字符' }
],
confirmPassword: [
{ required: true, message: '请确认密码' },
{
validator: (rule, value, allValues) => {
if (value !== allValues.password) {
return '两次输入的密码不一致';
}
return true;
},
message: '两次输入的密码不一致'
}
],
email: [
{ required: true, message: '邮箱不能为空' },
{ type: 'email', message: '请输入正确的邮箱格式' }
]
}
});
document.getElementById('register-form').addEventListener('submit', async (e) => {
e.preventDefault();
try {
const formData = await registerForm.validate();
console.log('注册数据:', formData);
alert('注册成功!');
registerForm.resetFields();
} catch (errors) {
console.log('验证失败:', errors);
}
});
function resetRegisterForm() {
registerForm.resetFields();
}
</script>加载 SanoUI 组件中...
场景 2:表单数据回填
从服务器获取数据后,回填到表单中。
html
<form class="sa-form" id="fill-form" style="max-width: 500px;" data-label-position="right" data-label-width="100px">
<div class="sa-form-item">
<label class="sa-form-item__label">姓名</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="name"
data-placeholder="请输入姓名"
style="width: 100%;"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">邮箱</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="email"
data-placeholder="请输入邮箱"
data-type="email"
style="width: 100%;"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">电话</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="phone"
data-placeholder="请输入电话"
data-type="tel"
style="width: 100%;"></div>
</div>
</div>
<div style="margin-top: 20px; display: flex; gap: 10px;">
<button type="button" class="sa-button sa-button--primary" onclick="loadUserData()">加载用户数据</button>
<button type="button" class="sa-button" onclick="clearForm()">清空表单</button>
<button type="button" class="sa-button" onclick="getFormData()">获取表单数据</button>
</div>
</form>
<script>
SA.init('body');
const fillForm = new SaForm('#fill-form', {
rules: {
name: [{ required: true, message: '姓名不能为空' }],
email: [
{ required: true, message: '邮箱不能为空' },
{ type: 'email', message: '请输入正确的邮箱格式' }
]
}
});
function loadUserData() {
setTimeout(() => {
const userData = {
name: '张三',
email: 'zhangsan@example.com',
phone: '13800138000'
};
fillForm.setFieldsValue(userData);
alert('数据已加载并回填到表单');
}, 500);
}
function clearForm() {
fillForm.resetFields();
alert('表单已清空');
}
function getFormData() {
const formData = fillForm.getFieldsValue();
alert('表单数据:\n' + JSON.stringify(formData, null, 2));
}
</script>加载 SanoUI 组件中...
注意事项
- 字段注册:表单字段必须通过
data-prop属性注册,或手动调用registerField()方法 - 验证时机:默认在字段失焦时验证,可以通过
trigger配置改变 - 异步验证:
validator函数支持返回 Promise,实现异步验证 - 错误显示:错误消息会自动显示在字段下方,可以通过
showMessage: false禁用 - 表单提交:建议在表单提交时调用
validate()方法进行完整验证
常见问题
Q: 如何获取表单的所有数据?
A: 使用 getFieldsValue() 方法:
javascript
const formData = form.getFieldsValue();Q: 如何设置表单字段的值?
A: 使用 setFieldsValue() 方法:
javascript
form.setFieldsValue({
username: 'admin',
email: 'admin@example.com'
});Q: 如何重置表单?
A: 使用 resetFields() 方法:
javascript
form.resetFields(); // 重置所有字段Q: 如何实现自定义验证?
A: 使用 validator 函数:
javascript
{
validator: (rule, value, allValues) => {
if (value !== allValues.password) {
return '两次输入的密码不一致';
}
return true;
}
}