TnForm-表单
此组件一般用于表单场景,可以配置 Input 输入框、Radio 单选框、Checkbox 多选框等,进行表单验证等。
组件位置
typescript
import TnForm from '@tuniao/tnui-vue3-uniapp/components/form/src/form.vue'
import TnFormItem from '@tuniao/tnui-vue3-uniapp/components/form/src/form-item.vue'
import TnForm from '@tuniao/tnui-vue3-uniapp/components/form/src/form.vue'
import TnFormItem from '@tuniao/tnui-vue3-uniapp/components/form/src/form-item.vue'
typescript
import TnForm from '@/uni_modules/tuniaoui-vue3/components/form/src/form.vue'
import TnFormItem from '@/uni_modules/tuniaoui-vue3/components/form/src/form-item.vue'
import TnForm from '@/uni_modules/tuniaoui-vue3/components/form/src/form.vue'
import TnFormItem from '@/uni_modules/tuniaoui-vue3/components/form/src/form-item.vue'
平台差异说明
App(vue) | H5 | 微信小程序 | 支付宝小程序 | ... |
---|---|---|---|---|
√ | √ | √ | √ | 适配中 |
基本使用
此组件一般是用于表单验证使用,每一个表单域由一个TnFormItem
组成,表单域中可以放置TnInput
、TnCheckbox
、TnRadio
、TnSwitch
等。
- 在表单中,通过 model 参数绑定一个对象,这个对象的属性名为各个
TnFormItem
的prop
属性,进行表单验证的时候,会根据prop
属性,从 model 中取值进行验证。 - 在
TnFormItem
中的各个表单组件,具体使用可以参考各个组件的文档。
vue
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import TnForm from '@tuniao/tnui-vue3-uniapp/components/form/src/form.vue'
import TnFormItem from '@tuniao/tnui-vue3-uniapp/components/form/src/form-item.vue'
import TnButton from '@tuniao/tnui-vue3-uniapp/components/button/src/button.vue'
import TnInput from '@tuniao/tnui-vue3-uniapp/components/input/src/input.vue'
import type { FormRules, TnFormInstance } from '@tuniao/tnui-vue3-uniapp'
const formRef = ref<TnFormInstance>()
// 表单数据
const formData = reactive({
username: '',
})
// 规则
const formRules: FormRules = {
username: [
{ required: true, message: '请输入用户名', trigger: ['change', 'blur'] },
{
pattern: /^[\w-]{4,16}$/,
message: '请输入4-16位英文、数字、下划线、横线',
trigger: ['change', 'blur'],
},
],
}
/* 提交表单 */
const submitForm = () => {
formRef.value?.validate((valid) => {
if (valid) {
uni.showToast({
title: '提交成功',
})
} else {
uni.showToast({
title: '表单校验失败',
icon: 'none',
})
}
})
}
</script>
<template>
<TnForm ref="formRef" :model="formData" :rules="formRules">
<TnFormItem label="用户名" prop="username">
<TnInput v-model="formData.username" />
</TnFormItem>
</TnForm>
<view class="tn-mt tn-flex-center">
<TnButton size="lg" @click="submitForm"> 提交 </TnButton>
</view>
</template>
<style lang="scss" scoped></style>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import TnForm from '@tuniao/tnui-vue3-uniapp/components/form/src/form.vue'
import TnFormItem from '@tuniao/tnui-vue3-uniapp/components/form/src/form-item.vue'
import TnButton from '@tuniao/tnui-vue3-uniapp/components/button/src/button.vue'
import TnInput from '@tuniao/tnui-vue3-uniapp/components/input/src/input.vue'
import type { FormRules, TnFormInstance } from '@tuniao/tnui-vue3-uniapp'
const formRef = ref<TnFormInstance>()
// 表单数据
const formData = reactive({
username: '',
})
// 规则
const formRules: FormRules = {
username: [
{ required: true, message: '请输入用户名', trigger: ['change', 'blur'] },
{
pattern: /^[\w-]{4,16}$/,
message: '请输入4-16位英文、数字、下划线、横线',
trigger: ['change', 'blur'],
},
],
}
/* 提交表单 */
const submitForm = () => {
formRef.value?.validate((valid) => {
if (valid) {
uni.showToast({
title: '提交成功',
})
} else {
uni.showToast({
title: '表单校验失败',
icon: 'none',
})
}
})
}
</script>
<template>
<TnForm ref="formRef" :model="formData" :rules="formRules">
<TnFormItem label="用户名" prop="username">
<TnInput v-model="formData.username" />
</TnFormItem>
</TnForm>
<view class="tn-mt tn-flex-center">
<TnButton size="lg" @click="submitForm"> 提交 </TnButton>
</view>
</template>
<style lang="scss" scoped></style>
vue
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import type { FormRules, TnFormInstance } from '@/uni_modules/tuniaoui-vue3'
const formRef = ref<TnFormInstance>()
// 表单数据
const formData = reactive({
username: '',
})
// 规则
const formRules: FormRules = {
username: [
{ required: true, message: '请输入用户名', trigger: ['change', 'blur'] },
{
pattern: /^[\w-]{4,16}$/,
message: '请输入4-16位英文、数字、下划线、横线',
trigger: ['change', 'blur'],
},
],
}
/* 提交表单 */
const submitForm = () => {
formRef.value?.validate((valid) => {
if (valid) {
uni.showToast({
title: '提交成功',
})
} else {
uni.showToast({
title: '表单校验失败',
icon: 'none',
})
}
})
}
</script>
<template>
<tn-form ref="formRef" :model="formData" :rules="formRules">
<tn-form-item label="用户名" prop="username">
<tn-input v-model="formData.username" />
</tn-form-item>
</tn-form>
<view class="tn-mt tn-flex-center">
<tn-button size="lg" @click="submitForm"> 提交 </tn-button>
</view>
</template>
<style lang="scss" scoped></style>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import type { FormRules, TnFormInstance } from '@/uni_modules/tuniaoui-vue3'
const formRef = ref<TnFormInstance>()
// 表单数据
const formData = reactive({
username: '',
})
// 规则
const formRules: FormRules = {
username: [
{ required: true, message: '请输入用户名', trigger: ['change', 'blur'] },
{
pattern: /^[\w-]{4,16}$/,
message: '请输入4-16位英文、数字、下划线、横线',
trigger: ['change', 'blur'],
},
],
}
/* 提交表单 */
const submitForm = () => {
formRef.value?.validate((valid) => {
if (valid) {
uni.showToast({
title: '提交成功',
})
} else {
uni.showToast({
title: '表单校验失败',
icon: 'none',
})
}
})
}
</script>
<template>
<tn-form ref="formRef" :model="formData" :rules="formRules">
<tn-form-item label="用户名" prop="username">
<tn-input v-model="formData.username" />
</tn-form-item>
</tn-form>
<view class="tn-mt tn-flex-center">
<tn-button size="lg" @click="submitForm"> 提交 </tn-button>
</view>
</template>
<style lang="scss" scoped></style>
label 对齐方式
通过设置label-position
属性可以改变表单域标签的位置,默认为right
,可选值为top
、left
, 当设为top
时标签会置于表单域的顶部
vue
<TnForm label-position="top">
<TnFormItem label="用户名" label-position="left">
<TnInput v-model="formData.username" />
</TnFormItem>
<TnFormItem label="邮箱">
<TnInput v-model="formData.email" />
</TnFormItem>
</TnForm>
<TnForm label-position="top">
<TnFormItem label="用户名" label-position="left">
<TnInput v-model="formData.username" />
</TnFormItem>
<TnFormItem label="邮箱">
<TnInput v-model="formData.email" />
</TnFormItem>
</TnForm>
表单校验
TnForm
组件允许你验证用户的输入是否符合规范,来帮助你找到和纠正错误。
TnForm
组件提供了表单验证的功能,只需为 rules
属性传入约定的验证规则,并将 TnFormItem
的 prop
属性设置为需要验证的特殊键值即可。 更多高级用法可参考async-validator。
typescript
const rules: FormProps['rules'] = {
username: [
{
required: true,
message: '请输入用户名',
trigger: 'blur',
},
{
min: 3,
max: 5,
message: '长度在 3 到 5 个字符',
trigger: 'blur',
},
],
}
const rules: FormProps['rules'] = {
username: [
{
required: true,
message: '请输入用户名',
trigger: 'blur',
},
{
min: 3,
max: 5,
message: '长度在 3 到 5 个字符',
trigger: 'blur',
},
],
}
自定义表单验证
typescript
const validatePass = (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请输入密码'))
} else {
if (formData.password !== '') {
if (!formRef.value) return
formRef.value.validateField('password', () => null)
}
callback()
}
}
const validateRePassword = (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== formData.password) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
}
const rules: FormProps['rules'] = {
username: [
{
required: true,
message: '请输入用户名',
trigger: 'blur',
},
{
min: 3,
max: 5,
message: '长度在 3 到 5 个字符',
trigger: 'blur',
},
],
password: [
{
validator: validatePass,
trigger: 'blur',
},
],
rePassword: [
{
validator: validateRePassword,
trigger: 'blur',
},
],
}
const validatePass = (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请输入密码'))
} else {
if (formData.password !== '') {
if (!formRef.value) return
formRef.value.validateField('password', () => null)
}
callback()
}
}
const validateRePassword = (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== formData.password) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
}
const rules: FormProps['rules'] = {
username: [
{
required: true,
message: '请输入用户名',
trigger: 'blur',
},
{
min: 3,
max: 5,
message: '长度在 3 到 5 个字符',
trigger: 'blur',
},
],
password: [
{
validator: validatePass,
trigger: 'blur',
},
],
rePassword: [
{
validator: validateRePassword,
trigger: 'blur',
},
],
}
尺寸控制
表单中的所有子组件都继承了该表单的 size
属性。 同样,TnFormItem
也有一个 size
属性。
如果希望某个表单项或某个表单组件的尺寸不同于 TnForm
上的 size
属性,直接为这个表单项或表单组件设置自己的 size
属性即可。
vue
<TnForm size="sm">
<TnFormItem label="用户名" label-position="left">
<TnInput v-model="formData.username" />
</TnFormItem>
<TnFormItem label="邮箱" size="lg">
<TnInput v-model="formData.email" />
</TnFormItem>
</TnForm>
<TnForm size="sm">
<TnFormItem label="用户名" label-position="left">
<TnInput v-model="formData.username" />
</TnFormItem>
<TnFormItem label="邮箱" size="lg">
<TnInput v-model="formData.email" />
</TnFormItem>
</TnForm>
Form API
Form Props
属性名 | 说明 | 类型 | 默认值 | 可选值 |
---|---|---|---|---|
model | 表单数据对象 | Object | - | - |
rules | 表单校验规则 | Object | Array | - | - |
size | 用于控制该表单内组件的尺寸 | String | - | sm 、lg |
disabled | 是否禁用该表单内的所有组件。 如果设置为 true , 它将覆盖内部组件的 disabled 属性 | Boolean | false | true |
label-position | label 标签位置 | String | right | right 、left 、top |
require-asterisk-position | 必填星号显示位置 | String | left | right |
hide-required-asterisk | 是否隐藏必填星号 | Boolean | false | true |
label-width | label 的宽度,默认单位为 rpx,支持传入数字、带单位的数值和auto | String | Number | - | - |
label-suffix | 表单域标签(label )的后缀 | String | - | - |
status-icon | 是否在输入框中显示校验结果反馈图标 | Boolean | false | true |
show-message | 是否显示校验结果 | Boolean | true | false |
validate-on-rule-change | 是否在校验规则修改后立马触发一次校验 | Boolean | true | false |
Form Events
事件名 | 说明 | 类型 |
---|---|---|
validate | 任一表单项被校验后触发 | (prop: FormItemProp, isValid: boolean, message: string) => void |
Form Methods
方法名 | 说明 | 类型 |
---|---|---|
validate | 对整个表单的内容进行验证。 接收一个回调函数,或返回 Promise | (callback?: (isValid: boolean, invalidFields?: ValidateFieldsError) => void) => Promise<boolean> |
validateField | 验证具体的某个字段 | (props?: Arrayable<FormItemProp>, callback?: (isValid: boolean, invalidFields?: ValidateFieldsError) => void) => Promise<void> |
resetFields | 重置该表单项,将其值重置为初始值,并移除校验结果 | (props?: Arrayable<FormItemProp>) => void |
clearValidate | 清理某个字段的表单验证信息 | (props?: Arrayable<FormItemProp>) => void |
Form Slots
插槽名 | 说明 | 子标签 |
---|---|---|
default | 自定义内容 | TnFormItem |
FormItem API
FormItem Props
属性名 | 说明 | 类型 | 默认值 | 可选值 |
---|---|---|---|---|
label | label 文本 | String | - | - |
label-width | label 的宽度,默认单位为 rpx,支持传入数字、带单位的数值和auto | String | Number | - | - |
label-position | label 标签位置 | String | right | right 、left 、top |
prop | model 的键名。 它可以是一个路径数组(例如 ['userInfo', 'hobby', 0] )。 在定义了 validate 、resetFields 的方法时,该属性是必填的 | String | Array<String> | - | - |
required | 是否为必填项,如不设置,则会根据校验规则确认 | Boolean | false | true |
rules | 表单校验规则 | Object | Array | - | - |
error | 表单域验证错误时的提示信息。设置该值会导致表单验证状态变为 error,并显示该错误信息。 | String | - | - |
validate-status | 校验状态 | FormItemValidateStates | - | - |
show-message | 是否显示校验结果 | Boolean | true | false |
size | 用于控制该表单内组件的尺寸 | String | - | sm 、lg |
FormItem Methods
方法名 | 说明 | 类型 |
---|---|---|
validate | 验证表单项 | (callback?: FormValidateCallback) => FormValidationResult |
resetFields | 对该表单项进行重置,将其值重置为初始值并移除校验结果 | () => void |
clearValidate | 移除该表单项的校验结果 | () => void |
FormItem Exposes
名称 | 说明 | 类型 |
---|---|---|
size | 表单项尺寸大小 | ComputedRef<'' | 'sm' | 'lg'> |
validateMessage | 校验消息 | Ref<string> |
validateState | 校验状态 | Ref<'' | 'error' | 'validating' | 'success'> |
FormItem Slots
插槽名 | 说明 |
---|---|
default | 自定义表单内容 |
label | 标签位置显示的内容 |