day06 - Ant Design - form 表单实现联动效果的几种方法

5,408 阅读1分钟

背景:总结后台系统中常用的表单功能,温故知新。

1.联动控制 form.item 的显示隐藏

根据 select 的选中值控制输入框的显示隐藏:

<Form
  name="myform"
  form={form}
  initialValues={initialValues}
  onFinish={onFinish}
>
  <Form.Item
    name="type"
    label="类型"
    rules={[{ required: true, message: '请选择' }]}
  >
    <Select placeholder="类型">
      <Option value={1}>option1</Option>
      <Option value={2}>option2</Option>
      <Option value={3}>option3</Option>
    </Select>
  </Form.Item>
  <Form.Item noStyle shouldUpdate>
    {({ getFieldValue }) => getFieldValue('type') === 3 && (
      <Form.Item name="value" label="名称">
        <Input />
      </Form.Item>
    )}
  </Form.Item>
</Form>

2.联动控制 Form.list 中的 form.item 交互,包括但不限于 disabled ,显示隐藏。

更多后台业务场景中,form 表单中会用到 Form.List 组件,本例子中,Form.List 组件包含三个子元素,前两个是下拉框,第三个根据第一个下拉框选中值动态显示为 input 或 select 组件。

当第一个下拉框选中值为 1 时,

  • 第二个下拉框默认选中 2 ,并且不能选择其他选项。
  • 第三个下拉框根据显示 select 并且隐藏 input 。

// 通过 onchange 方法获取当前选中值,动态控制其他 form.item 的状态
const changeValue = (key, value, index) => {
    const current = form.getFieldValue('myList')[index]

    if (current['key'] === 1) {
      current[key] = 2
      return
    }
    current[key] = value
}

// 表单联动效果关键是在 Form.List 最外层的 Form.Item 设置 shouldUpdate ,在需要实时更新的表单项 from.item 上也设置 shouldUpdate 即可。
// form.getFieldValue('myList')[index]?.key 方法可以获取 Form.List 中每一个数组元素的值。前提是你已经在在 <Form form={form} > 元素中添加 form 对象。
<Form
  name="myform"
  form={form}
  initialValues={initialValues}
  onFinish={onFinish}
>
  <Form.Item
    label="这是一个数组 list"
    colon={false}
    shouldUpdate
  >
    {() => (
      <Form.List name="myList" initialValue={[{}]}>
        {(fields, { add, remove }) => (
          <>
            {fields.map((field, index) => {
              const myListLength = fields.length
              const currentFormItem =
                form?.getFieldValue('myList')[index]
              return (
                <Space key={index}>
                  <Form.Item
                    {...field}
                    key={`${field.key}key`}
                    name={[field.name, 'key']}
                    fieldKey={[field.fieldKey, 'key']}
                  >
                    <Select
                      placeholder="请选择"
                      onChange={(value) => {
                        if (value === 1) {
                          changeValue('op', '', index)
                        }
                      }}
                    >
                      {[1,2,3,4].map((item, index) => (
                        <Option value={item} key={index}>
                          {item}
                        </Option>
                      ))}
                    </Select>
                  </Form.Item>
                  <Form.Item
                    {...field}
                    key={`${field.key}op`}
                    name={[field.name, 'op']}
                    fieldKey={[field.fieldKey, 'op']}
                    shouldUpdate
                  >
                    <Select
                      placeholder="请选择"
                      disabled={
                        currentFormItem?.key === 1
                      }
                    >
                      {['frontend','backend','android','ios'].map((item, index) => (
                        <Option value={item} key={index}>
                          {item}
                        </Option>
                      ))}
                    </Select>
                  </Form.Item>
                  <Form.Item
                    {...field}
                    key={`${field.key}value`}
                    name={[field.name, 'value']}
                    shouldUpdate
                  >
                    {form.getFieldValue('myList')[index]?.key !==
                    1 ? (
                      <Input style={{ width: 100 }} />
                    ) : (
                      <Select placeholder="请选择">
                        {[100,101,102].map((item, index) => (
                          <Option value={item} key={index}>
                            {item}
                          </Option>
                        ))}
                      </Select>
                    )}
                  </Form.Item>
                  <Form.Item>
                    <Button
                      type="primary"
                      shape="circle"
                      onClick={() => add({})}
                      icon={<PlusOutlined />}
                    />
                  </Form.Item>
                  {myListLength > 1 && (
                    <Form.Item>
                      <Button
                        shape="circle"
                        onClick={() => remove(field.name)}
                        icon={<MinusOutlined />}
                      />
                    </Form.Item>
                  )}
                </Space>
              )
            })}
          </>
        )}
      </Form.List>
    )}
  </Form.Item>
</Form>

写在最后: 后台系统千千万,唯有 copy 大法能统一。走过看过,如果觉得文章对你有帮助,那就顺手给个点赞!👍你的鼓励是我不断写文章的动力!😊