【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 事件实现弹出对话框。
import React, { useState } from 'react';
import { Modal, Button } from 'antd';
const ModalDemo = () => {
// 定义Hook state变量,控制对话框显隐,默认false
const [modalVisible, setModalVisible] = useState(false);
// 打开对话框方法,主要设置modalVisible=true
const openModal = () => {
setModalVisible(true);
};
// 对话框确定按钮点击的操作
const okModal = () => {
console.log('点击了对话框OK按钮!')
setModalVisible(false);
}
// render渲染div
return(
<>
<Button type="primary" onClick={openModal}>
打开基础对话框
</Button>
<Modal
title="基础Modal"
visible={modalVisible}
onCancel={()=>setModalVisible(false)}
onOk={okModal}
>
<p>这是一个简单对话框打开和关闭演示!</p>
</Modal>
</>
)
}
export default ModalDemo;
复制代码
代码中 OpenModal 方法中设置 modalVisible=true 来控制显示,另外默认 Modal 页脚会带有“确定”和“取消”两个按钮 ,其操作分别对应 **onCancel **和 **onOK **事件,取消一般是关闭动作,这里演示就在 { } 用箭头函数使其 modalVisible=false 隐藏对话框,确定按钮则单独写个函数方法,里边做一些逻辑操作,最后如处理正常后同样设置隐藏。
1.2 消息提示样式
只提供一个按钮用于关闭,一般用于各类的消息提示,其有 info,success,error,warning 四种类型(样式不同),使用的方法是直接在对应函数中通过 Modal.类型
创建,举一个成功消息提示的例子。
import { Modal, Button } from 'antd';
const ModalDemo = () => {
/** 确认对话框一般用于提示 **/
const successModal = () => {
Modal.success({
content: '成功:大奇与你一起,坚持学习,持续成长!',
});
};
// render渲染div
return(
<div id="confirmModal">
<Button type="link" onClick={successModal}>打开成功消息对话框</Button>
</div>
)
}
export default ModalDemo;
复制代码
此类型无需手动控制显示隐藏,方法中动态创建,点击知道了默认关闭对话框。<br />
2.组件 Form 表单
数据保存场景,并且需要对提交的字段进行校验时候,自带数据域管理的Form
表单组件最为合适。
https://ant.design/components/form-cn/
2.1 基础使用例子
使用 Form 需要 import { Form } from 'antd'
导入此组件,其<Form>
父组件中onFinish
事件用于提交表单且数据验证成功后的回调。子组件<Form.Item>
配置表单字段,用于数据双向绑定、校验、布局等,字段组件内两个基本属性 label
作用于页面显示,name
用户变量定义数据绑定。
import React, { useState } from 'react';
import { Form, Button, Input } from 'antd';
const FormDemo = () => {
// 提交按钮触发onFinish事件,其中values为表单的绑定参数集
const baseOnFinish = (values) => {
console.log('Form.Item绑定的字段集合:', values);
};
return(
<>
<Form onFinish={baseOnFinish}>
<Form.Item name="item1" label="字段1">
<Input/>
</Form.Item>
<Form.Item name="item2" label="字段2">
<Input width='200'/>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
提交
</Button>
</Form.Item>
</Form>
</>
)
}
export default FormDemo;
复制代码
特别注意 代码中 onFinish 事件的触发,需要通过一个 Button 按钮指定htmlType="submit"
即表单的属性。
除了上图中布局,组件还可以通过<Form layout="Vertical/Inline/Horizontal"> 指定样式,其他两种见下图。
2.2 规则校验
表单组件有很多属性可供大家去快速实现想要的效果,这里再讲一个用得比较多表单校验,使用属性 rules={[{规则}]}
进行配置,以上边的代码为基础来增加下规则代码,并看下效果。
代码中字段 1 设置了一个必填选项规则,字段二中设置两个基础规则,默认的 rules 触发条件onChange
在表单项内容发生变化校验,可以改成onBlur
提交时候触发。对于 Form 还提供了动态校验,自定义校验等,其中基础校验中可以满足大部分日常需求,不过官网没具体罗列,大奇通过查看代码给大家具体解释下。
interface BaseRule {
warningOnly?: boolean; // 非阻塞校验,即只提示,不作提交阻塞
enum?: StoreValue[]; // 枚举验证,即只能在符合的枚举列表中合法
len?: number; // 验证长度
max?: number; // 最大值 数字或字符
message?: string | ReactElement; // 错误提示消息
min?: number; // 最小值 数字或字符
pattern?: RegExp; // 正则表达式,比如邮箱、网址
required?: boolean; // 是否为必填
transform?: (value: StoreValue) => StoreValue;
type?: RuleType; // 将字段值转换成目标值后进行校验
whitespace?: boolean; // 如果字段仅包含空格则校验不通过,只在 type: 'string' 时生效
// 设置触发验证时机,必须是 Form.Item 的 validateTrigger 的子集
validateTrigger?: string | string[]; // onChange 或 onBlur
}
复制代码
3.项目新增功能
3.1 实现解析
经过上边的组件学习,接下来基于上述基础知识实战应用下,利用对话框内嵌表单,实现 Mock 平台项目增加功能,按照之前页面开发建议,简单画一个实现层级和为代码定义,有助于辅助开发。<br />
挑战:不看后边的完整代码,你能根据辅助草图,借助 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 中添加保存接口方法。
export async function saveProduct(data) {
return request('/api/mock/project/save', {
method: 'POST',
data
});
}
复制代码
3.3 功能实现
在实现项目增加弹窗表单功能代码中重点关注 onOk 中的实现,里边是按照上述 3.1 方式二触发的,并且需要额外增加逻辑,判断在有接口正常返回的时候调用表单resetFields
清除下历史记录,然后在设置关闭对话框的时候还要记得重新请求下 Table 表,确保数据展示最新的项目数据。
import React, { useState } from "react";
import { useRequest } from 'umi';
// 引入组件依赖
import { Button, Space, Table, Modal, Form, Input } from "antd";
const { TextArea } = Input;
// 导入sever接口请求方法
import { getProductList, saveProduct } from "@/pages/Project/service";
... 省略其他之前代码 ...
const Project = () => {
// 获取全部项目数据
const {data:useProjectList, error, loading, run: reloadProjectList} = useRequest(getProductList);
// 定义表单控制和隐藏,处理相关动作
const [projectVisible, setProjectVisible] = useState(false);
const addAction = () => { // 打开表单对话框
setProjectVisible(true);
}
// 经创建的 form 控制实例
const [formProject] = Form.useForm();
// 返回渲染的组件
return (
<>
<Button
onClick={addAction}
type="primary"
style={{
marginBottom: 16,
}}
>
项目添加
</Button>
<Modal
title="项目添加"
visible={projectVisible}
destroyOnClose="true"
onCancel={()=>setProjectVisible(false)}
onOk={() => {
formProject
.validateFields()
.then(async (values) => {
const data = { // 构造接口请求body
name: values.name,
owner: values.owner,
desc: values.desc,
type: 'public', // 默认公开,暂时固定
operator: '大奇' // 还没讲到用户管理,暂时指定
}
const resp = await saveProduct(data);
if (resp.success) {
formProject.resetFields(); // 表单清除历史
setProjectVisible(false); // 关闭表单对话框
reloadProjectList(); // 刷新项目列表
}
})
.catch((info) => {
console.log('保存项目异常', info);
});
}}
>
<Form form={formProject}>
<Form.Item
name='name'
label='名称'
rules={[
{
required: true,
message: '项目名称为必填项!',
},
]}
>
<Input placeholder="请输入项目名称"></Input>
</Form.Item>
<Form.Item name='owner' label='负责人'>
<Input placeholder="项目相负责人"></Input>
</Form.Item>
<Form.Item name="desc" label="更多信息">
<TextArea/>
</Form.Item>
</Form>
</Modal>
...省略的table代码....
</>
)
}
export default Project;
复制代码
有些细节的说明都标注在了代码中,在自己的实践中可以对照参考。<br />功能实代码实现后,重新运行前后端服务,来看下成果,见 GIF 演示。
总结一下本篇分享主要学习了 Modal 和 Form 两个组件,并运用其组合实现了当前页面上的项目添加功能,这些基础的内容都很重要,切记好好理解掌握和运用。
评论