Form 表单
示例
表单-水平布局
<script lang="ts">
let loginForm: Form
let loginData = $state({ username: '', password: '' })
// 自定义 required
function usrRule(username: string) {
if (!username?.length) return '请输入用户名'
}
// 密码复杂度验证
function pwdRule(pwd: string) {
return (
/^(?=.*[a-zA-Z])(?=.*\d)[\w!@#$%^&*()-+=]{8,}$/.test(pwd) ||
'8位以上英文+数字'
)
}
// 表单提交
async function handleSubmit(form: Form) {
const valid = await form.validate()
if (valid) {
showToast({ text: '登录' })
} else {
showToast({ text: '内容有误' })
}
}
</script>
<Form
bind:this={loginForm}
bind:data={loginData}
header="表单-水平布局"
layout="horizontal"
--sunp-label-width="80px"
>
<FormItem label="用户名" field="username" required={usrRule}>
<Input
bind:value={loginData.username}
placeholder="请输入用户名"
autocomplete="username"
/>
</FormItem>
<FormItem label="密码" field="password" required rules={[pwdRule]}>
<Input
type="password"
bind:value={loginData.password}
placeholder="请输入密码"
autocomplete="current-password"
/>
</FormItem>
</Form>
<div class="bg-white px-4 py-2">
<Space>
<Button color="primary" onclick={() => handleSubmit(loginForm)}>提交</Button
>
<Button
color="normal"
onclick={() => loginForm.reset({ username: '', password: '' })}
>重置</Button
>
</Space>
</div>
表单-垂直布局-默认
<script lang="ts">
let loginForm2: Form
let loginData2 = $state<[username?: string, password?: string]>(['', ''])
</script>
<Form bind:this={loginForm2} bind:data={loginData2} header="表单-垂直布局-默认">
<FormItem label="用户名" field={0} required={usrRule}>
<Input
bind:value={loginData2[0]}
placeholder="请输入用户名"
autocomplete="username"
/>
</FormItem>
<FormItem label="密码" field={1} required rules={[pwdRule]}>
<Input
type="password"
bind:value={loginData2[1]}
placeholder="请输入密码"
autocomplete="current-password"
/>
</FormItem>
</Form>
<div class="bg-white px-4 py-2">
<Space>
<Button color="primary" onclick={() => handleSubmit(loginForm2)}
>提交</Button
>
<Button color="normal" onclick={() => loginForm2.reset(['', ''])}
>重置</Button
>
</Space>
</div>
表单-可点击项
<Form header="表单-可点击项" layout="horizontal">
<FormItem
label="点我试试"
clickable
onClick={() => showToast({ text: 'Hello' })}
>
<div class="w-full">试试就试试</div>
</FormItem>
</Form>
表单-混合布局
<Form header="表单-混合布局" layout="horizontal">
<FormItem label="文本-水平">
<Input placeholder="请填写文本" />
</FormItem>
<FormItem label="备注-垂直" layout="vertical">
<Textarea placeholder="请填写备注" />
</FormItem>
<FormItem label="步进器-水平">
<Stepper />
</FormItem>
<FormItem label="步进器-垂直" layout="vertical">
<Stepper />
</FormItem>
<FormItem label="开关-水平">
<Switch />
</FormItem>
<FormItem label="开关-垂直" layout="vertical">
<Switch />
</FormItem>
</Form>
Form
属性
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
header | 标题 | string | Snippet | undefined |
layout | 布局模式 | 'horizontal' | 'vertical' | 'vertical' |
data | 表单对象 | Record |
undefined |
方法
方法 | 说明 | 类型 |
---|---|---|
validate | 表单验证 (异步) | () => Promise |
reset | 表单数据重置,并清除验证错误 | (data: Record |
FormHeader
Form 的子元素,通常作为 Form 的子标题或者间隔使用。
FormItem
属性
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
label | 标签名 | string | Snippet | undefined |
layout | 布局模式 | 'horizontal' | 'vertical' | 'vertical' |
field | 提供表单条目对应的字段 | PropertyKey | undefined |
required | 是否必填/自定义错误信息/自定义校验逻辑 | boolean | string | [Rule](#rule-type) | false |
rules | 自定义校验逻辑 | Array<[Rule](#rule-type)> | undefined |
error | 表单条目错误信息 | string | $bindable() |
clickable | 是否可以点击。'auto' 表示由 FormItem 的子组件控制 | boolean | 'auto' | 'auto' |
事件
事件 | 说明 | 类型 |
---|---|---|
onClick | FormItem 点击事件。clickable === false 时不会触发此事件 | () => void |
onclick | HTML 原生的点击事件。注意与 onClick 的区别 | (e: MouseEvent) => void |
表单验证
必须为 Form 提供 data 属性。必须为 FormItem 提供 field 属性。
FormItem 提供了 required
和 rules
这两个校验项。校验函数会优先校验 required 逻辑,然后按数组顺序校验 rules。
Required
当 required 有值时,会显示 * 星号。
以下 value 不能通过 required 校验:
- null | undefined
- 空字符串/空白
- 空数组
- 无效的数字
- 无效的日期
Rule
/**
* 自定义表单条目的校验逻辑
* @val 当前表单的值
* @return 如果返回值的类型为 string,且截断前后空白后字符串长度 > 0,则表示未通过验证
*/
type Rule = (val: any) => any | PromiseLike<any>
CSS 变量
属性 | 说明 | 默认值 |
---|---|---|
--sunp-label-width | 标签宽度。表单布局为 'horizontal' 时有效 | 102px |
FormArray
TODO