import React, { useMemo, useState } from "react";
import { Form, Button, Radio } from "antd";
import { componentMap, registerFormComponent } from './componentMap'
const MyRadioGroup = React.forwardRef(({ options = [], value, onChange, ...rest }, ref) => (
<>
<div>自定义</div>
<Radio.Group ref={ref} value={value} onChange={onChange} {...rest}>
{options.map(opt => (
<Radio key={opt.value} value={opt.value}>{opt.label}</Radio>
))}
</Radio.Group>
</>
));
registerFormComponent('radioGroup', MyRadioGroup);
// 1. 定义所有表单项
const formItems = [
{
id: "name",
type: "input",
label: "姓名",
next: (values) => {
if (values.name === 'tt') {
return "age"
}
if (values.name) {
return "gender"
}
return null
}, // 姓名填写后进入性别
},
{
id: "gender",
type: "select",
label: "性别",
options: [
{ label: "男", value: "male" },
{ label: "女", value: "female" },
{ label: "其他", value: "other" },
],
next: (values) => {
if (values.gender === "other") {
return null
}
return "age"
// values.gender === "other" ? "customGender" : "age"
},
},
{
id: "age",
type: "input",
label: "年龄",
inputType: "number",
next: (values) => (values.age ? values.age >= 18 ? "job" : 'school' : null),
},
{
id: "job",
type: "select",
label: "职业",
// options 可以是函数,接收当前表单值
options: (values) => {
if (values.gender === "male") {
return [
{ label: "工程师", value: "engineer" },
{ label: "司机", value: "driver" },
{ label: "其他", value: "other" },
];
}
if (values.gender === "female") {
return [
{ label: "教师", value: "teacher" },
{ label: "护士", value: "nurse" },
{ label: "其他", value: "other" },
];
}
// 默认
return [
{ label: "学生", value: "student" },
{ label: "其他", value: "other" },
];
},
next: () => null,
},
{
id: "school",
type: "select",
label: "学校",
options: [
{ label: "学校1", value: "school1" },
{ label: "学校2", value: "school2" },
{ label: "学校3", value: "school3" },
],
next: (value) => {
console.log(111, value)
if (value.school === 'school3') {
return 'radioGroup'
}
return null
},
},
{
id: 'radioGroup',
type: 'radioGroup',
options: [
{ label: "1", value: "1" },
{ label: "2", value: "2" },
],
next: (value) => {
return null
},
}
];
// 2. 动态链式表单组件
function DynamicChainForm({ items, firstId }) {
const [form] = Form.useForm();
const [chain, setChain] = useState([firstId]);
console.log('componentMap:', componentMap)
// 监听表单值变化,动态生成链
const handleValuesChange = (changed, all) => {
let ids = [firstId];
let currentId = firstId;
while (true) {
const item = items[currentId];
if (!item || !item.next) break;
const nextId = item.next(all);
if (!nextId || ids.includes(nextId)) break;
ids.push(nextId);
currentId = nextId;
}
setChain(ids);
};
const handleFinish = (values) => {
// 提交表单数据
console.log("表单提交:", values);
};
return (
<Form
form={form}
onValuesChange={handleValuesChange}
onFinish={handleFinish}
layout="vertical"
>
{/* {chain.map((id) => {
const item = items[id];
if (!item) return null;
if (item.type === "input") {
return (
<Form.Item key={id} name={id} label={item.label}>
<Input type={item.inputType || "text"} />
</Form.Item>
);
}
if (item.type === "select") {
return (
<Form.Item key={id} name={id} label={item.label}>
<Select>
{(typeof item.options === "function"
? item.options(form.getFieldsValue())
: item.options
).map(opt => (
<Select.Option key={opt.value} value={opt.value}>
{opt.label}
</Select.Option>
))}
</Select>
</Form.Item>
);
}
return null;
})} */}
{chain.map((id) => {
const item = items[id];
if (!item) return null;
const Comp = componentMap[item.type];
if (!Comp) return null;
// 统一处理 options
let options = item.options;
if (typeof options === "function") {
options = options(form.getFieldsValue());
}
// 统一传递 options 给所有组件
return (
<Form.Item key={id} name={id} label={item.label}>
<Comp
type={item.inputType || "text"}
options={options}
{...item.props}
/>
</Form.Item>
);
})}
<Form.Item>
<Button type="primary" htmlType="submit">
提交
</Button>
</Form.Item>
</Form>
);
}
// 3. 主组件
const ZKLinkageForms = () => {
// 用 useMemo 防止每次渲染都重新生成
const itemsMap = useMemo(() => {
const map = {};
formItems.forEach((item) => {
map[item.id] = item;
});
return map;
}, []);
return <DynamicChainForm items={itemsMap} firstId="name" />;
};
export default ZKLinkageForms