Mock平台头图7.png

【Mock平台】为系列测试开发教程,从0到1编码带你一步步使用Spring Boot 和 Antd React框架完成搭建一个测试工具平台,希望作为一个实战项目对各位的测试开发学习之路有帮助,欢迎关注《大奇测试开发》公众号、博客、语雀等原创渠道获取最佳阅读,大奇一个专注测试技术干货原创与分享的家伙。

1.组件Modal对话框

在页面交互上当想做不打断工作流,不跳转新页面的操作,常用的组件之一就是Modal对话框,场景比如简单添加、查看详细、二次确认等。

https://ant.design/components/modal-cn/

1.1 默认标准使用

使用 Modal 需要导入组件 **import { Modal } from 'antd'**通过属性**visible**控制显隐,其中还有两个主要的触发事件 **onOk**点击确定回调, **onCancel**点击遮罩层或右上角叉或取消按钮的回调。

为此我们创建一个演示空白页,内部定义useState变量,通过一个基础的Button按钮触发 onClick 事件
�实现弹出对话框。

  1. import React, { useState } from 'react';
  2. import { Modal, Button } from 'antd';
  3. const ModalDemo = () => {
  4. // 定义Hook state变量,控制对话框显隐,默认false
  5. const [modalVisible, setModalVisible] = useState(false);
  6. // 打开对话框方法,主要设置modalVisible=true
  7. const openModal = () => {
  8. setModalVisible(true);
  9. };
  10. // 对话框确定按钮点击的操作
  11. const okModal = () => {
  12. console.log('点击了对话框OK按钮!')
  13. setModalVisible(false);
  14. }
  15. // render渲染div
  16. return(
  17. <>
  18. <Button type="primary" onClick={openModal}>
  19. 打开基础对话框
  20. </Button>
  21. <Modal
  22. title="基础Modal"
  23. visible={modalVisible}
  24. onCancel={()=>setModalVisible(false)}
  25. onOk={okModal}
  26. >
  27. <p>这是一个简单对话框打开和关闭演示!</p>
  28. </Modal>
  29. </>
  30. )
  31. }
  32. export default ModalDemo;

代码中OpenModal方法中设置modalVisible=true来控制显示,另外默认Modal页脚会带有“确定”和“取消”两个按钮 ,其操作分别对应 onCancel onOK 事件,取消一般是关闭动作,这里演示就在 { } 用箭头函数使其modalVisible=false隐藏对话框,确定按钮则单独写个函数方法,里边做一些逻辑操作,最后如处理正常后同样设置隐藏。
Mock平台-07开发:项目管理(三)组件Modal和Form讲解,并利用其实现添加功能 - 图2

1.2 消息提示样式

只提供一个按钮用于关闭,一般用于各类的消息提示,其有 infosuccesserrorwarning 四种类型(样式不同),使用的方法是直接在对应函数中通过 Modal.类型创建,举一个成功消息提示的例子。

  1. import { Modal, Button } from 'antd';
  2. const ModalDemo = () => {
  3. /** 确认对话框一般用于提示 **/
  4. const successModal = () => {
  5. Modal.success({
  6. content: '成功:大奇与你一起,坚持学习,持续成长!',
  7. });
  8. };
  9. // render渲染div
  10. return(
  11. <div id="confirmModal">
  12. <Button type="link" onClick={successModal}>打开成功消息对话框</Button>
  13. </div>
  14. )
  15. }
  16. export default ModalDemo;

此类型无需手动控制显示隐藏,方法中动态创建,点击知道了默认关闭对话框。
image.png

2.组件Form表单

数据保存场景,并且需要对提交的字段进行校验时候,自带数据域管理的Form表单组件最为合适。

https://ant.design/components/form-cn/

2.1 基础使用例子

使用 Form 需要 **import { Form } from 'antd'**导入此组件,其<Form>父组件中**onFinish**事件用于提交表单且数据验证成功后的回调。子组件<Form.Item>配置表单字段,用于数据双向绑定、校验、布局等,字段组件内两个基本属性 label 作用于页面显示,name 用户变量定义数据绑定。

  1. import React, { useState } from 'react';
  2. import { Form, Button, Input } from 'antd';
  3. const FormDemo = () => {
  4. // 提交按钮触发onFinish事件,其中values为表单的绑定参数集
  5. const baseOnFinish = (values) => {
  6. console.log('Form.Item绑定的字段集合:', values);
  7. };
  8. return(
  9. <>
  10. <Form onFinish={baseOnFinish}>
  11. <Form.Item name="item1" label="字段1">
  12. <Input/>
  13. </Form.Item>
  14. <Form.Item name="item2" label="字段2">
  15. <Input width='200'/>
  16. </Form.Item>
  17. <Form.Item>
  18. <Button type="primary" htmlType="submit">
  19. 提交
  20. </Button>
  21. </Form.Item>
  22. </Form>
  23. </>
  24. )
  25. }
  26. export default FormDemo;

特别注意,代码中onFinish事件的触发,需要通过一个Button按钮指定htmlType="submit"即表单的属性。
image.png
除了上图中布局,组件还可以通过

指定样式,其他两种见下图。
image.png

2.2 规则校验

表单组件有很多属性可供大家去快速实现想要的效果,这里再讲一个用得比较多表单校验,使用属性 rules={[{规则}]}进行配置,以上边的代码为基础来增加下规则代码,并看下效果。
image.png
代码中字段1设置了一个必填选项规则,字段二中设置两个基础规则,默认的rules触发条件onChange在表单项内容发生变化校验,可以改成onBlur提交时候触发。对于Form还提供了动态校验,自定义校验等,其中基础校验中可以满足大部分日常需求,不过官网没具体罗列,大奇通过查看代码给大家具体解释下。

  1. interface BaseRule {
  2. warningOnly?: boolean; // 非阻塞校验,即只提示,不作提交阻塞
  3. enum?: StoreValue[]; // 枚举验证,即只能在符合的枚举列表中合法
  4. len?: number; // 验证长度
  5. max?: number; // 最大值 数字或字符
  6. message?: string | ReactElement; // 错误提示消息
  7. min?: number; // 最小值 数字或字符
  8. pattern?: RegExp; // 正则表达式,比如邮箱、网址
  9. required?: boolean; // 是否为必填
  10. transform?: (value: StoreValue) => StoreValue;
  11. type?: RuleType; // 将字段值转换成目标值后进行校验
  12. whitespace?: boolean; // 如果字段仅包含空格则校验不通过,只在 type: 'string' 时生效
  13. // 设置触发验证时机,必须是 Form.Item 的 validateTrigger 的子集
  14. validateTrigger?: string | string[]; // onChange 或 onBlur
  15. }

3.项目新增功能

3.1 实现解析

经过上边的组件学习,接下来基于上述基础知识实战应用下,利用对话框内嵌表单,实现Mock平台项目增加功能,按照之前页面开发建议,简单画一个实现层级和为代码定义,有助于辅助开发。
Mock平台-07开发:项目管理(三)组件Modal和Form讲解,并利用其实现添加功能 - 图7

挑战:不看后边的完整代码,你能根据辅助草图,借助IDE提示和组件官网独立敲代码实现出来吗?

在上边组件基础例子中,组件之间是相互独立的,这里会有用哪个按钮进行保存操作,Form中通过onFinish事件,Modal组件中还有默认的按钮,样式上可以提供两种思路:
方式一:隐藏掉Modal页脚 footer="false", 内层表单设定两个按钮实现提交和关闭;
方式二:Modal中onOk事件借助 Form.useForm()调用表单内部validateFields进行验证和数据提交,完全替代onFinish事件,官方有具体例子。我的代码也将参考此例实现。

https://ant.design/components/form-cn/#components-form-demo-form-in-modal

3.2 服务接口

后端的接口在之前的篇幅中已经实现过,这里仅是在service.js 中添加保存接口方法。

  1. export async function saveProduct(data) {
  2. return request('/api/mock/project/save', {
  3. method: 'POST',
  4. data
  5. });
  6. }

3.3 功能实现

在实现项目增加弹窗表单功能代码中重点关注 onOk 中的实现,里边是按照上述3.1方式二触发的,并且需要额外增加逻辑,判断在有接口正常返回的时候调用表单resetFields清除下历史记录,然后在设置关闭对话框的时候还要记得重新请求下Table表,确保数据展示最新的项目数据。

  1. import React, { useState } from "react";
  2. import { useRequest } from 'umi';
  3. // 引入组件依赖
  4. import { Button, Space, Table, Modal, Form, Input } from "antd";
  5. const { TextArea } = Input;
  6. // 导入sever接口请求方法
  7. import { getProductList, saveProduct } from "@/pages/Project/service";
  8. ... 省略其他之前代码 ...
  9. const Project = () => {
  10. // 获取全部项目数据
  11. const {data:useProjectList, error, loading, run: reloadProjectList} = useRequest(getProductList);
  12. // 定义表单控制和隐藏,处理相关动作
  13. const [projectVisible, setProjectVisible] = useState(false);
  14. const addAction = () => { // 打开表单对话框
  15. setProjectVisible(true);
  16. }
  17. // 经创建的 form 控制实例
  18. const [formProject] = Form.useForm();
  19. // 返回渲染的组件
  20. return (
  21. <>
  22. <Button
  23. onClick={addAction}
  24. type="primary"
  25. style={{
  26. marginBottom: 16,
  27. }}
  28. >
  29. 项目添加
  30. </Button>
  31. <Modal
  32. title="项目添加"
  33. visible={projectVisible}
  34. destroyOnClose="true"
  35. onCancel={()=>setProjectVisible(false)}
  36. onOk={() => {
  37. formProject
  38. .validateFields()
  39. .then(async (values) => {
  40. const data = { // 构造接口请求body
  41. name: values.name,
  42. owner: values.owner,
  43. desc: values.desc,
  44. type: 'public', // 默认公开,暂时固定
  45. operator: '大奇' // 还没讲到用户管理,暂时指定
  46. }
  47. const resp = await saveProduct(data);
  48. if (resp.success) {
  49. formProject.resetFields(); // 表单清除历史
  50. setProjectVisible(false); // 关闭表单对话框
  51. reloadProjectList(); // 刷新项目列表
  52. }
  53. })
  54. .catch((info) => {
  55. console.log('保存项目异常', info);
  56. });
  57. }}
  58. >
  59. <Form form={formProject}>
  60. <Form.Item
  61. name='name'
  62. label='名称'
  63. rules={[
  64. {
  65. required: true,
  66. message: '项目名称为必填项!',
  67. },
  68. ]}
  69. >
  70. <Input placeholder="请输入项目名称"></Input>
  71. </Form.Item>
  72. <Form.Item name='owner' label='负责人'>
  73. <Input placeholder="项目相负责人"></Input>
  74. </Form.Item>
  75. <Form.Item name="desc" label="更多信息">
  76. <TextArea/>
  77. </Form.Item>
  78. </Form>
  79. </Modal>
  80. ...省略的table代码....
  81. </>
  82. )
  83. }
  84. export default Project;

有些细节的说明都标注在了代码中,在自己的实践中可以对照参考。
功能实代码实现后,重新运行前后端服务,来看下成果,见GIF演示。

总结一下本篇分享主要学习了Modal和Form两个组件,并运用其组合实现了当前页面上的项目添加功能,这些基础的内容都很重要,切记好好理解掌握和运用。最后为了保持错误及时修正和良好的学习阅读,系列文章会同步发表到语雀和博客,同时开放个人微信,入交流群、资料地址获取等欢迎联系大奇。