Form/FormFooter/FormItem 表单
寄语:表单这块一直没有能深度去思考,之前做过一般跟其他 UI 库一样校验,但是都觉得不满意,现只保留最简单最布局功能。
注:
- 这几个组件主要聚焦于布局。
- 如果想要复杂的表单设计或者校验功能,可以借助 formilyjs 来实现。
Import
import { TaForm, TaFormFooter, TaFormItem } from 'tantalum-ui-mobile-react'
具体的引入方式可以参考引入组件。
Form Slots
children
<TaForm>
<TaInput type="text" />
</TaForm>
renderFooter
<TaForm renderFooter={() => <TaButton form-type="submit">提交</TaButton>} />
FormFooter Slots
children
<TaForm.Footer>
<TaButton form-type="submit">提交</TaButton>
</TaForm.Footer>
FormItem Props
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
error | string | string[] | 否 | 错误提示信息 | |
label | string | 否 | 设置该行名称,比如 昵称 | |
required | boolean | false | 否 | 是否必填,设置 true 后 label 会展示必填* |
FormItem Slots
default
<TaForm.Item>
<TaInput type="text" />
</TaForm.Item>
支持表单的组件
- Input
- RadioGroup
- CheckboxGroup
- Switch
- Stepper
- Slider
- Range
- Rate
- Calendar
- DatePicker
- Cascader
- Picker
- ImageUploader
与 Formily 配合
关于 Formily 的介绍可以查看阿里巴巴的官网。
安装
npm install --save @formily/core @formily/react
对 FormItem
做下适配
FormilyFormItem.js
:
import { TaFormItem } from 'tantalum-ui-mobile-react'
import { connect, mapProps } from '@formily/react'
import { isVoidField } from '@formily/core'
export default connect(
TaFormItem,
mapProps(
{ validateStatus: true, title: 'label', required: true },
(props, field) => {
if (isVoidField(field)) return props
if (!field) return props
const getMessage = () => {
if (field.validating) return
if (props.error) return props.error
if (field.selfErrors.length) return field.selfErrors
// if (field.selfWarnings.length) return split(field.selfWarnings)
// if (field.selfSuccesses.length) return split(field.selfSuccesses)
}
return {
error: getMessage()
}
}
)
)
设计表单
import {
TaForm,
TaGroup,
TaInput,
TaPicker,
TaCalendar,
TaCascader,
TaSwitch,
TaRate,
TaSlider,
TaStepper,
TaRadioGroup,
TaCheckboxGroup,
TaImageUploader,
TaButton,
showToast,
ImageUploaderUploadReady
} from '@/index'
import { multiOptions, regionOptions } from '../Picker/data'
import { createForm, setValidateLanguage } from '@formily/core'
import { FormProvider, Field, FormConsumer } from '@formily/react'
import FormilyFormItem from './FormilyFormItem'
const genderOptions = [
{ label: '男', value: 1 },
{ label: '女', value: 2 }
]
const characters = ['活泼', '内向', '高冷']
setValidateLanguage('zh-CN')
const form = createForm({ validateFirst: true })
export default function ExpForm() {
function getDataUrl(file: File) {
return new Promise<string>(resolve => {
const fr = new FileReader()
fr.onload = function (e) {
resolve((e.target?.result as string) ?? '')
}
fr.readAsDataURL(file)
})
}
const hookUpload: ImageUploaderUploadReady = (file, handlers) => {
getDataUrl(file).then(url => {
handlers.success(url)
})
}
function onSubmit(...args: any[]) {
console.log(...args)
showToast('校验通过')
}
return (
<>
<TaGroup title="Formily">
<FormProvider form={form}>
<Field
name="nickname"
title="昵称"
required
component={[
TaInput,
{ placeholder: '请输入昵称', showClear: true }
]}
decorator={[FormilyFormItem]}
/>
<Field
name="avatar"
title="头像"
required
component={[
TaImageUploader,
{ uploadReady: hookUpload, columnNumber: 1, maxCount: 1 }
]}
decorator={[FormilyFormItem]}
/>
<Field
name="gender"
title="性别"
required
component={[
TaRadioGroup,
{
options: genderOptions
}
]}
decorator={[FormilyFormItem]}
/>
<Field
name="weight"
title="体重Kg"
required
component={[TaSlider, { showValue: true, min: 35, max: 120 }]}
decorator={[FormilyFormItem]}
/>
<Field
name="season"
title="季节"
required
component={[
TaPicker,
{ options: multiOptions, placeholder: '选择季节' }
]}
decorator={[FormilyFormItem]}
/>
<Field
name="birthday"
title="生日"
required
component={[TaCalendar, { placeholder: '选择生日' }]}
decorator={[FormilyFormItem]}
/>
<Field
name="character"
title="性格"
required
component={[TaCheckboxGroup, { options: characters }]}
decorator={[FormilyFormItem]}
/>
<Field
name="region"
title="地区"
required
component={[
TaCascader,
{
placeholder: '选择地区',
fieldNames: { value: 'label' },
options: regionOptions
}
]}
decorator={[FormilyFormItem]}
/>
<Field
name="happinessIndex"
title="幸福指数"
required
component={[TaRate, { allowHalf: true }]}
decorator={[FormilyFormItem]}
/>
<Field
name="stepper"
title="步进器"
required
component={[TaStepper, { max: 10, step: 0.2, decimalLength: 1 }]}
decorator={[FormilyFormItem]}
/>
<Field
name="agree"
title="认可"
required
component={[TaSwitch]}
decorator={[FormilyFormItem]}
/>
<FormConsumer>
{form => (
<>
<pre className="exp-form-json">
{JSON.stringify(form.values, null, 2)}
</pre>
<TaForm.Footer>
<TaButton
type="primary"
onClick={() => {
form.submit(onSubmit)
}}
>
提交
</TaButton>
</TaForm.Footer>
</>
)}
</FormConsumer>
</FormProvider>
</TaGroup>
</>
)
}