FormStep 分步表单
分步表单组件
提示
可以参考 FormPopup 文档中的例子 创建一个弹出层式的分步表单
Markup Schema
tsx
import { Form, FormButtonGroup, FormItem, FormStep, Input, Submit } from '@silver-formily/antd-mobile'
import { createForm } from '@silver-formily/core'
import { createSchemaField, FormConsumer } from '@silver-formily/react'
import { Button } from 'antd-mobile'
import { useState } from 'react'
const SchemaField = createSchemaField({ components: { FormStep, FormItem, Input } })
function onSubmit(values: unknown) {
return Prompts.alert(JSON.stringify(values, null, 2))
}
export default function BasicDemo() {
const [form] = useState(() => createForm())
const [step] = useState(() => FormStep.createFormStep())
return (
<Form form={form}>
<SchemaField>
<SchemaField.Void name="steps" x-component="FormStep" x-component-props={{ formStep: step }}>
<SchemaField.Void name="contact" title="联系信息" x-component="FormStep.StepPane" x-component-props={{ description: '填写联系人' }}>
<SchemaField.String name="name" title="姓名" required x-decorator="FormItem" x-component="Input" x-component-props={{ placeholder: '请输入姓名' }} />
</SchemaField.Void>
<SchemaField.Void name="delivery" title="配送信息" x-component="FormStep.StepPane">
<SchemaField.String name="address" title="地址" required x-decorator="FormItem" x-component="Input" x-component-props={{ placeholder: '请输入配送地址' }} />
</SchemaField.Void>
<SchemaField.Void name="confirm" title="确认提交" x-component="FormStep.StepPane">
<SchemaField.String name="remark" title="备注" x-decorator="FormItem" x-component="Input.TextArea" x-component-props={{ placeholder: '选填' }} />
</SchemaField.Void>
</SchemaField.Void>
</SchemaField>
<FormConsumer>
{() => (
<FormButtonGroup>
<Button disabled={!step.allowBack} onClick={() => step.back()}>上一步</Button>
{step.allowNext
? <Button color="primary" onClick={() => step.next()}>下一步</Button>
: <Submit onSubmit={onSubmit}>提交</Submit>}
</FormButtonGroup>
)}
</FormConsumer>
</Form>
)
}JSON Schema、内部实例与隐藏步骤条
不传 formStep 时自动创建控制器,步骤面板内的组件可通过 useFormStep() 读取。hideSteps 隐藏进度条,仅显示当前面板。
tsx
import { Form, FormButtonGroup, FormItem, FormStep, Input, Submit, useFormStep } from '@silver-formily/antd-mobile'
import { createForm } from '@silver-formily/core'
import { createSchemaField, observer } from '@silver-formily/react'
import { Button } from 'antd-mobile'
import { useState } from 'react'
const Actions = observer(() => {
const step = useFormStep()
return (
<FormButtonGroup>
<Button disabled={!step.allowBack} onClick={() => step.back()}>上一步</Button>
{step.allowNext
? <Button color="primary" onClick={() => step.next()}>下一步</Button>
: <Submit onSubmit={onSubmit}>提交</Submit>}
</FormButtonGroup>
)
})
const SchemaField = createSchemaField({ components: { FormStep, FormItem, Input, Actions } })
function onSubmit(values: unknown) {
return Prompts.alert(JSON.stringify(values, null, 2))
}
export default function InternalInstanceDemo() {
const [form] = useState(() => createForm())
return (
<Form form={form}>
<SchemaField schema={{
type: 'object',
properties: {
steps: {
'type': 'void',
'x-component': 'FormStep',
'x-component-props': { hideSteps: true },
'properties': {
contact: {
'type': 'void',
'title': '联系信息',
'x-component': 'FormStep.StepPane',
'properties': {
name: { 'type': 'string', 'title': '姓名', 'required': true, 'x-decorator': 'FormItem', 'x-component': 'Input', 'x-component-props': { placeholder: '请输入姓名' } },
actions: { 'type': 'void', 'x-component': 'Actions' },
},
},
delivery: {
'type': 'void',
'title': '配送信息',
'x-component': 'FormStep.StepPane',
'properties': {
address: { 'type': 'string', 'title': '地址', 'required': true, 'x-decorator': 'FormItem', 'x-component': 'Input', 'x-component-props': { placeholder: '请输入配送地址' } },
actions: { 'type': 'void', 'x-component': 'Actions' },
},
},
},
},
},
}}
/>
</Form>
)
}API
FormStep
| 属性 | 类型 | 说明 |
|---|---|---|
formStep | IFormStep | 外部控制器,默认内部创建 |
current | number | 受控步骤索引,从 0 开始,优先于控制器状态 |
hideSteps | boolean | 隐藏步骤条,默认 false |
其余步骤条属性参考 antd-mobile Steps。超出范围的索引会限制在有效步骤内,非有限数值归零。受控模式需由调用方更新 current,通常建议使用控制器驱动步骤。
FormStep.StepPane
面板属性 IFormStepPaneProps 参考 antd-mobile Step 官方文档。Schema 的 title 作为默认步骤标题,x-component-props.title 可覆盖。面板仅作为 Schema 容器,子字段由 FormStep 按当前步骤渲染。
控制器
FormStep.createFormStep(defaultCurrent?: number) 返回响应式 IFormStep:
| 属性 / 方法 | 说明 |
|---|---|
current | 当前步骤索引 |
allowNext / allowBack | 是否可以前进 / 后退 |
setCurrent(index) | 跳转到指定步骤,不触发校验 |
next() | 返回 Promise;校验通过后前进,失败时停留;校验期间忽略重复调用 |
back() | 返回上一步,不触发校验 |
submit(onSubmit?) | 调用当前表单的 submit,返回提交结果 Promise |
未激活面板使用 hidden 状态,保留值并跳过校验。提交沿用表单当前可见字段的校验规则,不会挂载或重新校验未访问的步骤;需要确保必填步骤都经过校验时,应使用 next() 顺序前进。
useFormStep
useFormStep(): IFormStep,也可通过 FormStep.useFormStep() 调用。必须在当前步骤面板的后代组件内使用,在 FormStep 外使用会抛错。读取响应式属性的按钮组件需使用 observer 包装。
IFormStepProps、IFormStepPaneProps、IFormStep 均可从包根入口导入。