You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何用Form Builder实现多列表单?求替代方案

多列表单实现方案(Form Builder及替代方案)

一、使用Form Builder实现多列表单

完全可以用Form Builder包实现多列表单,核心思路是结合CSS布局组件(Grid/Flexbox)拆分表单字段,让Form Builder负责渲染单个表单控件,外层布局容器控制列的分配。

以React生态的Form Builder为例,简单实现方式如下:

import { Formik, Form } from 'formik';
import { FormBuilder } from 'react-form-builder';

const MultiColumnForm = () => {
  // 定义字段时指定列宽(对应Grid的col-span值)
  const formFields = [
    { name: 'fullName', label: '姓名', type: 'text', col: 6 },
    { name: 'email', label: '邮箱', type: 'email', col: 6 },
    { name: 'age', label: '年龄', type: 'number', col: 4 },
    { name: 'gender', label: '性别', type: 'select', options: ['男', '女'], col: 4 },
    { name: 'city', label: '城市', type: 'text', col: 4 },
    // 扩展更多10-20个字段...
  ];

  return (
    <Formik initialValues={{}} onSubmit={(values) => console.log('提交数据:', values)}>
      <Form className="grid grid-cols-12 gap-4 p-4">
        {formFields.map(field => (
          <div key={field.name} className={`col-span-${field.col}`}>
            <FormBuilder field={field} />
          </div>
        ))}
        <div className="col-span-12 mt-4">
          <button type="submit" className="px-4 py-2 bg-blue-500 text-white rounded">提交</button>
        </div>
      </Form>
    </Formik>
  );
};

通过给每个字段分配col属性,结合CSS Grid的col-span类,就能轻松实现多列布局,同时借助Form Builder简化单个控件的渲染逻辑。

二、替代方案(适合10-20个字段的简洁实现)

如果Form Builder不符合需求,以下几种方案更适合字段较多的场景:

1. UI组件库原生多列表单

比如Ant Design、Element UI这类成熟组件库,自带表单布局能力,通过Row和Col组件直接拆分列,同时集成了校验、状态管理等功能,代码更简洁:

import { Form, Input, Select, Button, Row, Col } from 'antd';

const MultiColumnForm = () => {
  const handleSubmit = (values) => console.log('提交数据:', values);

  return (
    <Form onFinish={handleSubmit} layout="vertical" className="p-4">
      <Row gutter={16}>
        <Col span={12}>
          <Form.Item label="姓名" name="fullName" rules={[{ required: true, message: '请输入姓名' }]}>
            <Input />
          </Form.Item>
        </Col>
        <Col span={12}>
          <Form.Item label="邮箱" name="email" rules={[{ required: true, type: 'email', message: '请输入合法邮箱' }]}>
            <Input />
          </Form.Item>
        </Col>
      </Row>
      <Row gutter={16}>
        <Col span={8}>
          <Form.Item label="年龄" name="age" rules={[{ required: true, type: 'number', min: 18 }]}>
            <Input.Number />
          </Form.Item>
        </Col>
        <Col span={8}>
          <Form.Item label="性别" name="gender" rules={[{ required: true }]}>
            <Select options={[{ label: '男', value: 'male' }, { label: '女', value: 'female' }]} />
          </Form.Item>
        </Col>
        <Col span={8}>
          <Form.Item label="城市" name="city" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
        </Col>
      </Row>
      {/* 更多字段行... */}
      <Form.Item>
        <Button type="primary" htmlType="submit">提交</Button>
      </Form.Item>
    </Form>
  );
};

2. 低代码表单渲染库

像FormRender、XRender这类工具,支持通过JSON配置生成多列表单,无需手写大量组件代码,适合字段数量多的场景:

import FormRender from '@form-render/core';
import SchemaField from '@form-render/core/dist/SchemaField';

const MultiColumnForm = () => {
  const schema = {
    type: 'object',
    properties: {
      fullName: { type: 'string', title: '姓名', ui: { span: 12 } },
      email: { type: 'string', title: '邮箱', format: 'email', ui: { span: 12 } },
      age: { type: 'number', title: '年龄', ui: { span: 8 } },
      gender: { type: 'string', title: '性别', enum: ['男', '女'], ui: { span: 8 } },
      city: { type: 'string', title: '城市', ui: { span: 8 } },
      // 更多字段...
    },
    ui: { grid: { cols: 24 } } // 全局列数配置
  };

  const onSubmit = (values) => console.log('提交数据:', values);

  return <SchemaField schema={schema} onSubmit={onSubmit} />;
};

只需在字段的ui.span中指定列宽,就能自动生成多列表单,大幅减少代码量。

3. 自定义封装布局表单组件

如果需要高度定制,可以自己封装一个基于Grid/Flex的表单容器,统一处理布局和表单状态,比如:

import { useState } from 'react';

const MultiColumnFormContainer = ({ fields, onSubmit }) => {
  const [formData, setFormData] = useState({});

  const handleChange = (name, value) => {
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  return (
    <form onSubmit={(e) => { e.preventDefault(); onSubmit(formData); }} className="grid grid-cols-12 gap-4 p-4">
      {fields.map(field => (
        <div key={field.name} className={`col-span-${field.col}`}>
          <label className="block mb-1">{field.label}</label>
          {field.type === 'text' && <input type="text" value={formData[field.name] || ''} onChange={(e) => handleChange(field.name, e.target.value)} className="w-full p-2 border rounded" />}
          {/* 扩展其他输入类型... */}
        </div>
      ))}
      <div className="col-span-12 mt-4">
        <button type="submit" className="px-4 py-2 bg-blue-500 text-white rounded">提交</button>
      </div>
    </form>
  );
};

// 使用示例
const App = () => {
  const fields = [
    { name: 'fullName', label: '姓名', type: 'text', col: 6 },
    { name: 'email', label: '邮箱', type: 'text', col: 6 },
    // 更多字段...
  ];

  return <MultiColumnFormContainer fields={fields} onSubmit={(values) => console.log(values)} />;
};

内容的提问来源于stack exchange,提问作者GeekzSG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 09:15:33