Form表单
用于数据校验和提交
按钮导致的表单提交
3.0.11 之前
当 Form 组件下存在 button 时,点击 button 会默认触发表单验证
这并不是 bug,这是HTML的标准行为,button 的默认type就是 submit
不想触发该行为的话将 button 的 type 设置了 button 即可
该问题已于2.6.10解决,无需额外处理,已自动阻止表单自动提交事件
排列方向
通过修改
Form的align属性可以实现,整体的水平或者垂直排列方式考虑到一些情况下可能需要更为灵活的排列方式 故此
FormItem也可以设置align属性来修改对齐方式,该项优先级更大两者的
align可选值有horizontalvertical,默认为horizontal
Form设置align为vertical
Form设置align为horizontal
Form设置align为vertical,email项设置align为horizontal
<template>
<div class="space-y-2">
<p class="font-bold">Form设置align为vertical</p>
<Form :form="form" :schema="schema" align="vertical">
<FormItem name="email" label="邮箱">
<TextInput v-model="form.email" placeholder="请输入邮箱" />
</FormItem>
<FormItem name="password" label="密码">
<TextInput v-model="form.password" type="password" placeholder="请输入密码" />
</FormItem>
</Form>
<p class="font-bold">Form设置align为horizontal</p>
<Form :form="form" :schema="schema" align="horizontal">
<FormItem name="email" label="邮箱">
<TextInput v-model="form.email" placeholder="请输入邮箱" />
</FormItem>
<FormItem name="password" label="密码">
<TextInput v-model="form.password" type="password" placeholder="请输入密码" />
</FormItem>
</Form>
<p class="font-bold">Form设置align为vertical,email项设置align为horizontal</p>
<Form :form="form" :schema="schema" align="vertical">
<FormItem name="email" label="邮箱" align="horizontal">
<TextInput v-model="form.email" placeholder="请输入邮箱" />
</FormItem>
<FormItem name="password" label="密码">
<TextInput v-model="form.password" type="password" placeholder="请输入密码" />
</FormItem>
</Form>
</div>
</template>
<script setup lang="ts">
import { Form, FormItem, useYup, TextInput } from 'li-daisy'
import { ref } from 'vue'
const form = ref({
email: '',
password: '',
status: true,
})
const yup = useYup()
const schema = yup.object({
email: yup.string().email().required('请输入邮箱').trim(),
password: yup.string().required('请输入密码').min(6).trim(),
status: yup.bool().isTrue('状态错误'),
})
</script>使用yup验证
Form组件由 vee-validate 和 yup 封装而成,yup作为其认证库组件内部封装了一个简单的
yup全局实例,其代码见 仓库源码借此,用户可以自行选择如何使用
yup,如果需要更小的打包体积建议使用按需从yup导入,即不要使用import * as yup from 'yup'这种方式去使用yup同理用户可以自行定义一系列基础配置,比如基础验证消息中文翻译,
i18n等下面将演示如何去使用
yup,以及如何实现一个简单的配置
<template>
<Form :form="form" label-width="40px" :schema="schema" align="vertical">
<FormItem name="email" label="邮箱">
<TextInput v-model="form.email" placeholder="请输入邮箱" />
</FormItem>
<FormItem name="password" label="密码">
<TextInput v-model="form.password" type="password" placeholder="请输入密码" />
</FormItem>
</Form>
</template>
<script setup lang="ts">
import { Form, FormItem, TextInput } from 'li-daisy'
import * as yupInstance from 'yup'
import { ref } from 'vue'
const useYup = () => {
yupInstance.setLocale({
string: {
email: '${path} 必须是有效的邮箱地址',
min: '${path} 必须是长度不小于 ${min} 个字符',
},
})
return yupInstance
}
const form = ref({
email: '',
password: '',
status: true,
})
const yup = useYup()
const schema = yup.object({
email: yup.string().email().required('请输入邮箱').trim(),
password: yup.string().required('请输入密码').min(6).trim(),
})
</script>例子
验证表单(注册示例)
通过
FormRef的validate方法校验整个表单,返回一个 Promise校验通过时进入
then回调,校验失败时进入catch回调该方法只校验单个字段,失败时智慧展示所有字段的错误提示
<template>
<Form ref="formRef" :form="form" :schema="schema" align="vertical">
<FormItem name="email" label="邮箱">
<TextInput v-model="form.email" placeholder="请输入邮箱" />
</FormItem>
<FormItem name="password" label="密码">
<TextInput v-model="form.password" type="password" placeholder="请输入密码" />
</FormItem>
<FormItem name="re_password" label="重复密码">
<TextInput v-model="form.re_password" type="password" placeholder="请重复输入密码" />
</FormItem>
<FormItem>
<button class="btn w-full" @click="handleRegister">注册用户</button>
</FormItem>
</Form>
</template>
<script setup lang="ts">
import { Form, FormItem, useYup, TextInput, Notification, Message } from 'li-daisy'
import type { FormRef } from 'li-daisy'
import { ref } from 'vue'
const formRef = ref<FormRef>()
const form = ref({
email: '',
password: '',
re_password: '',
})
const yup = useYup()
const schema = yup.object({
email: yup.string().email().required('请输入邮箱').trim(),
password: yup
.string()
.required('请输入密码')
.min(8, '密码不得少于八位')
.matches(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/,
'密码必须包含大小写字母、数字和特殊字符'
)
.trim(),
re_password: yup
.string()
.required('请再次输入密码')
.oneOf([yup.ref('password')], '两次密码输入不一致'),
})
const handleRegister = async () => {
formRef.value
?.validate()
.then(() => {
Message.info('注册成功')
})
.catch(() => {
Notification.warning({
title: '表单验证失败',
message: '表单填写有误',
})
})
}
</script>验证单个字段
通过
FormRef的validateField方法校验指定字段,返回一个 Promise校验通过时进入
then回调,校验失败时进入catch回调,并可获取错误信息该方法只校验单个字段,失败时智慧展示指定字段的错误提示
<template>
<Form ref="formRef" :form="form" :schema="schema" align="vertical">
<FormItem name="email" label="邮箱">
<TextInput v-model="form.email" placeholder="请输入邮箱" />
</FormItem>
<FormItem name="password" label="密码">
<TextInput v-model="form.password" type="password" placeholder="请输入密码" />
</FormItem>
<FormItem>
<div class="space-y-3">
<button class="btn w-full" @click="handleValidateEmail">验证邮箱</button>
<button class="btn w-full" @click="handleValidatePassword">验证密码</button>
</div>
</FormItem>
</Form>
</template>
<script setup lang="ts">
import { Form, FormItem, useYup, TextInput, Notification, Message } from 'li-daisy'
import type { FormRef } from 'li-daisy'
import { ref } from 'vue'
const formRef = ref<FormRef>()
const form = ref({
email: '',
password: '',
})
const yup = useYup()
const schema = yup.object({
email: yup.string().email().required('请输入邮箱').trim(),
password: yup.string().required('请输入密码').min(6).trim(),
})
const handleValidateEmail = () => {
formRef.value
?.validateField('email')
.then(() => {
Message.info('注册成功')
})
.catch(err => {
Notification.warning({
title: '验证失败',
message: err,
})
})
}
const handleValidatePassword = () => {
formRef.value
?.validateField('password')
.then(() => {
Message.info('注册成功')
})
.catch(err => {
Notification.warning({
title: '验证失败',
message: err,
})
})
}
</script>检测验证是否通过
提供两种互补方式,选择取决于场景(UI 状态 vs 提交时需触发异步 schema 规则)。
isValid(响应式)- 描述:响应式布尔值,用于反映当前表单是否有错误(基于内部 errors)。
- 适用场景:实时 UI 控制,例如禁用/启用提交按钮、显示简单状态提示。
- 注意:不会主动触发 yup 的异步 test 或远程校验,仅反映已被触发并记录的错误状态。
validate/validateField(手动触发的异步校验)- 描述:调用时会执行 yup schema 上的所有规则(包括自定义的异步 test),返回 Promise。
- validate(): 校验整个表单,常用于提交前的最终校验。
- validateField(name): 校验单个字段,适合失焦校验或需要远程校验的场景。
- 适用场景:提交时需等待异步规则(如远程唯一性校验)、对单字段做即时校验。
API
Attributes
Form
| 属性值 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| form | 待验证的响应对象 | Ref<Record<string, any>> Reactive<Record<string, any>> | - |
| schema | yup验证规则 | GenericObject | - |
| label-width | label宽度 | string | '60px' |
| align | 对齐方向 | ['horizontal','vertical'] | 'vertical' |
FormItem
| 属性值 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| name | schema的key | string | - |
| label | label名 | string | - |
| trigger | 错误信息显示时机 | ['change','blur','input'] | 'change' |
| align | 对齐方向 | ['horizontal','vertical'] | 'vertical' |
Slots
Form
| 插槽名 | 说明 |
|---|---|
| default | 默认插槽 |
FormItem
| 插槽名 | 说明 |
|---|---|
| default | 默认插槽 |
Expose
Form
| 方法名 | 说明 | 类型 |
|---|---|---|
| validate | 验证整个表单 | () => Promise<void> |
| validateField | 验证某个字段 | (fieldName: string) => Promise<void> |
| isValid | 验证是否通过 | boolean |