复杂页面 - 表单

网站开发中,仅仅是简单展示一下数据还远远不够,我们还会需要对数据进行更新的操作。

本小节中,我们会在页面中添加一个按钮。点击后弹出对话框,允许用户输入一条新的数据并进行更新。

相关代码:https://github.com/ant-design/react-tutorial

引入相关依赖

我们将本次需要的组件引入进来。

import { Table, Modal, Button, Form, Input } from 'antd';

const FormItem = Form.Item;

对话框

我们在页面中插入新建按钮和对话框组件。

<div>
  <Table ... />

  <Button>新建</Button>
  <Modal title="新建记录">
    ...
  </Modal>
</div>

其中,对于 Modal 组件,我们可以通过 visible 属性来控制是否显示。

因此,我们需要将其在 state 中进行管理。

class List extends React.Component {
  state = {
    visible: false,
  };

  // ...
}

按钮事件

让我们为按钮添加相应事件,使其可以改变 state 中 visible 的值。

class List extends React.Component {
  showModal = () => {
    this.setState({ visible: true });
  };

  // ...
}
<Button onClick={this.showModal}>新建</Button>

设置好后,我们页面中点击按钮便会弹出对话框了。

表单

antd 提供了一套非常强大的表单组件,大部分情况下只需要简单的几步配置便可以实现验证功能。首先,我们需要将页面与表单进行关联:

export default connect(mapStateToProps)(Form.create()(List));

其中,最主要的代码是:

Form.create()(List)

这段代码的作用是创建一个高阶组件,为页面组件 List 提供表单所需要的内容(this.props.form)。

现在,我们来让对话框关联 visible 并且添加上表单支持:

render() {
    const { visible } = this.state;
    const { form: { getFieldDecorator } } = this.props;

    // ...

    return (
      <div>
        {/* ... */}

        <Modal
          title="新建记录"
          visible={visible}
        >
          <Form>
            <FormItem label="名称">
              {getFieldDecorator('name', {
                rules: [{ required: true }],
              })(
                <Input />
              )}
            </FormItem>
            <FormItem label="描述">
              {getFieldDecorator('desc')(
                <Input />
              )}
            </FormItem>
            <FormItem label="链接">
              {getFieldDecorator('url', {
                rules: [{ type: 'url' }],
              })(
                <Input />
              )}
            </FormItem>
          </Form>
        </Modal>
      </div>
    );
  }
}

我们可以看到表单组件是通过 Form 与 Form.Item (我们之前定义了 FormItem = Form.item) 配合使用,其中每一个 Form.Item 都是一个表单域。而 getFieldDecorator 是用于将包裹的组件与表单进行双向绑定使用。

然后,我们添加表单处理逻辑。添加确认和取消方法。

撤销操作

重置 visible 属性为 false 以关闭对话框。

handleCancel = () => {
  this.setState({
    visible: false,
  });
}

确定操作

我们通过 validateFields 方法验证表单是否完成填写,通过便提交添加操作。

handleOk = () => {
  const { dispatch, form: { validateFields } } = this.props;

  validateFields((err, values) => {
    if (!err) {
      dispatch({
        type: 'cards/addOne',
        payload: values,
      });
      // 重置 `visible` 属性为 false 以关闭对话框
      this.setState({ visible: false });
    }
  });
}

其中, dispatch 的 'cards/addOne' 请参考我们提供的对应样例中 src/model/cardssrc/service/cardsmock/cards 的代码。

该内容已经在第三章中讲解因而不再重复。

最后,我们为 Modal 添加事件处理:

<Modal
  title="新建记录"
  visible={visible}
  onOk={this.handleOk}
  onCancel={this.handleCancel}
>
  ...
</Modal>

自定义控件

在 antd 中,我们提供了诸如 Input, Select 之类的用于接收用户输入的组件。

但是如果这些不满足你的需要时该怎么办呢?

比如你如果需要一个富文本输入框,又或者是一个复杂的多行内容输入的表格。

我们怎么可以添加这些复杂的组件,让它们可以和 antd 的 Form 组件一起使用呢?

其实很简单,在上面我们介绍了 getFieldDecorator 这个方法,它执行后会返回一个函数,那个函数接收一个参数,那个参数就是一个输入组件。

比如在上面的例子中它可能是 <Input /> 也有可能是 <Select />。

但是它并没有被局限在 antd 支持的组件内,你完全可以传入你自己的一个组件,比如下面的示例:

<FormItem label="自定义输入">
  {getFieldDecorator('custom', {
    rules: [{ required: true }],
  })(
    <YourInput />
  )}
</FormItem>

其中,只要 YourInput 这个组件满足如下三个条件即可:

  • 提供受控属性 value 或其它与 valuePropName 的值同名的属性。
  • 提供 onChange 事件或 trigger 的值同名的事件。
  • 不能是函数式组件。

具体的可运行的例子你可以参考 Ant Design 官网的例子

所以,如果你需要在表单中添加一个富文本组件,那么你可以在 Ant Design 官网推荐的社区精选组件中找到合适你项目的富文本编辑器组件。

然后你也可以自定义一个组件,该组件应该封装你找到的编辑器子组件并满足上面说的三个条件,这样你就可以在你的表单中使用它了。

思考

洋洋洒洒我们写了这么多的代码,是时候思考一下其他问题了。

目前的代码能够实现功能,但是这是最好的实现吗?

函数名和变量是否可以再改改?

是否可以把一部分代码抽离出来做成独立的模块呢?

现在页面样式布局是否还能再进行一些调整呢?

等等……

这就交给各位独立思考啦。

相关文章

感觉本篇文章不错,对你有收获?

¥我要小额赞助,鼓励作者写出更好的教程
80 160 120

作者:

  • 出处: https://www.mi360.cn/articles/171
  • 本文版权归作者,欢迎转载,但未经作者同意必须保留 此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

评论区

最新评论

扫码关注