接口自动化平台(二):antd pro开发平台的一些准备工作

目录

1. 回顾antd pro 结构

2. 用antd pro实现todolist

3. 从接口获取数据,而不是页面上直接获取

4. 搜索功能

5. 删除功能

6. 页面分页

7.删除?刷新?

8. 测试平台


1. 回顾antd pro 结构

(1)重要菜单:

config菜单下routes.ts里可以设置其他相关目录的结构,添加新页面的内容。

即:src/pages/下添加新文件夹,对应新页面

(2)useState, useRef, useEffect:

hooks使得函数式组件中用useState, useRef, useEffect

(3)const [count, setCount] = useState(0):第一个参数是变量,第二个参数是异步函数。

!!!重要说明!!!

1) setCount函数是一个异步的过程,不是同步的。

即:setCount不会阻塞它后面的命令的执行,有可能后面的命令在它之前执行,后面命令用用到的值可能就是setCount更新之前的值。

2)setCount函数第一个参数是count, 还可以有第二个参数 (回调函数?)…..待研究

针对这个问题,运用到的知识点:setState, setCount还可以传第二个参数。

3)setCount有两种写法:第一种写法是第二种写法的语法糖。

第一种写法:

可以用第二个参数,即回调函数:

类似:this.setState({todos: newTodos}, () => {console.log(this.state.todos)})

这样的话,就能让其顺序执行,先更新,再打印

第二种写法:

this.setState中的函数,可以只需要一个回调函数(最常用这个),传一个参数(原始的state),然后修改这个参数,返回修改之后的参数。

即如果setState只有一个参数,那这个参数是它的第二个参数,是一个回调函数。

为什么这个地方讲到这个问题?

是因为在函数式组件中,这是setCount里可用一个回调函数的原因。setCount(count => count+1)。跟之前的例子对应上了:

(4)const myRef = useRef(0)  //定义useRef对象

在某个标签中<BBB ref={myRef}>   //用useRef对象标识组件标签

最后在需要的地方使用:myRef.current.value   //通过useRef,调用标签的值

注意跟JS原生的event从input里取值的区别:event.target.value

(5)useEffect

第一个参数:回调函数(参数),在componentDidmount和componentWillUnmount阶段都会执行。

第二个参数是限制在什么方法下/情况下才执行这个useEffect.

2. 用antd pro实现todolist

说明:

(1)模态框:避免过多的页面跳转,新页面会以一个弹窗的形式弹出来显示。

(2)相比于原生的table, 更多的使用Protable

(3)VScode 里创建函数组件快捷方式: rfc。类式组件快捷方式:rcc

(4)常规操作:需要用到什么组件,先拷贝官网上相应组件的代码信息,后面没有用的再清掉。

(5)一般我们用<PageContainer>,会帮我们把路径和标题信息加载好。也可以用<ProCard>。

(6)定义一些字段,以及它们的类型,常用的是string和number。类似Java的接口

Type DataType = {
        id: string;
        name: string;
        age: number;
        todo: string
}

(7)定义表头(第一列)的信息,以及每一列的取值/从传入数据中的匹配项


const columes: ProColumnType<DataType>[ ] = [     //这个columes是一个数组,切记

{
        title: ‘Name’,
        dataIndex: ‘name’,
        …
},     //数组元素1
{
        title: ‘Age’,
        dataIndex: ‘age’,
        …
},    //数组元素2
{
        title: ‘Todo’,
        dataindex: ‘todo’,
        …
},   //数组元素3
{
        title: ‘Action’,
        …
        render:() =>{}
}    //数组元素4
]

(8)数据源

const data: DateType[ ] = [
{
        id: ‘1’,
        name: ‘Mike’,
        age: ’30’,
        todo: ‘吃饭’,
},
{
        id: ‘2’,
        name: ‘Kate’,
        age: ’40’,
        todo: ‘睡觉’,
}]

(9)return里的Protable, 将官网上的示例代码拷过去之后,再根据情况删除一些我们不需要的功能,模块,简化代码。 在<ProTable />标签里面加表头columns,footer等内容。

(10)<ProTable />标签里,最重要的是columns (表头字段), dataSource

columns = {columns}

dataSource = {data}

(11)把data放到函数组件里的useState

(12)要实现delete操作:

把columns放到函数里。

columns里action字段的render方法的回调,它自己可以获取一些参数,其中第二个参数record就是当前操作的某个todo项,根据这个信息,就能判断要删除确切的哪一项。

遍历每一条todo时,到action这一块,发现没有dataIndex, 就不像上面那样直接赋值action, 而是等点击的时候,它就去执行render里的回调方法。(每次都渲染render, 执不执行回调方法看有没有监听到动作)

columns里面就很像之前的<Item />组件。

{
      title: 'Action',
      key: 'action',
      sorter: true,
      valueType: 'option',
      render: (_, record) => [
        <a key="delete" onClick={
          () => {
              const newTodos = todos.filter(todoObj => {
              return todoObj.id !== record.id
            })
            setTodos(newTodos)
          }
        }> Delete </a>,
      ],
},     //语法说明:render: (text, record, _, action) => {}

(13)要实现新增操作:使用模态框

根据ProTable,加一个新增按钮,这里的<Button>是常规的,但真正使用时,用ProComponents里的Modal表单,新建表单ModalForm,ProForm.Group等。

toolBarRender = {( ) => [    //这里箭头指向的是一个数组,意思是这个地方可以包含多个按钮

        <Button type=“primary” onClick={ ( ) => { }}>

        新增

        </Button>

]}

实例:

toolBarRender={   //放在<ProTable />标签中
          () => [
            <ModalForm<DataType>
                title="新建TODO"
                formRef={formRef}
                trigger={   //触发表单
                        <Button type="primary">
                        <PlusOutlined />
                          新建Todo
                        </Button>
                  }
                submitter={{   // 实现了重置按钮
                        searchConfig: {
                            resetText: '重置',
                        },
                        resetButtonProps: {
                                onClick: () => {
                                    formRef.current?.resetFields(); //提交后清空模态框
                                    //   setModalVisible(false);
                                  },
                        },
              }}
               onFinish={async (values) => {  //提交表单时的操作
                        const { name, age, todo } = values;  //解构赋值
                        const newTodos = [{ id: nanoid(), name, age, todo }, ...todos] //扩展运算符
                        setTodos(newTodos);
                        message.success('提交成功');
                        //formRef.current?.resetFields();  //提交后清空模态框
                        return true;
              }}
            >  //ModalForm的前一个标签在这里结束,下面是ModalForm要展示的内容,最后是结束标签

              <ProForm.Group>
                <ProFormText width="sm" name="name" label="姓名" placeholder="请输入姓名" />
                <ProFormText width="sm" name="age" label="年龄" placeholder="请输入年龄" />
                <ProFormText width="sm" name="todo" label="todo" placeholder="请输入todo" />
              </ProForm.Group>

            </ModalForm>
          ]
}

补充解析:

(1)onFinish中,用异步方法,values传的是下方ProForm中输入的新建内容 

(2)const newTodos = [{ id: nanoid(), name, age, todo }, ...todos] 这里用了语法糖

(3)提交后清空模态框:formRef.current?.resetFields();

(4)安装nanoid, yarn add nanoid

(5)实现新增页面的重置/清空操作

具体参考 Modal/Drawer中重置表单:通formRef重置。

上面代码的submitter部分,实现了重置按钮。

如果想要在提交新todo时同步更新,则无需上面的submitter部分,只需要在onFinish触发部分,添加:formRef.current?.resetFields();

3. 从接口获取数据,而不是页面上直接获取

(1)request从接口获取的数据(JSON格式等)和自定义的dataSource

(2)拿到request里的内容(数组)之后,它也会自动去跟columns遍历匹配,dataindex对得上的话,就会显示在页面上。

(3)之后如果需要调用后端信息的话,通常会编写一个service.ts,存放各种方法,请求,接口,跟后端联调。

(4)因为这里后端的还没写好,没起来,所以这里依赖一下mock接口,在listTableList.ts里改

(5)在TodoList里也新建一个service.ts,然后在TodoList的index.ts里修改request部分:

request = {(params, sorter, filter) => queryTodos({...params, sorter, filter})}  //不再用dataSource

1)mock里的listTavleList.ts:  //模拟后端接口数据

这里最好用data,不要用别的变量。如果用别的变量的话,需要额外处理。

export default {   //将这些接口和里面的内容暴露出来,供service.ts调用,service.ts中的接口,再供前端调用
  'GET /api/rule': getRule,
  'POST /api/rule': postRule,
  'GET /api/todos': {
    data:[
      {
        id: '001',
        name: 'Kate',
        age: 18,
        todo: '吃饭'
      },
      {
        id: '002',
        name: 'Ellie',
        age: 19,
        todo: '睡觉'
      },
      {
        id: '003',
        name: 'Joe',
        age: 20,
        todo: '上班'
      },
    ]
  }
};

2)TodoList里新建service.ts:

import request from '@/utils/request';

export async function queryTodos(params?: any){
    return request('/api/todos', {
        params,
    });
}

3)TodoList里的index.tsx:

request={(params, sorter, filter) => queryTodos({ ...params, sorter, filter })}  
// queryTodos对应service.ts里的函数

(6)每次启动页面,或者搜索(默认自己带的,自己写的render之类的在这里不算)之后,相当于都重新调request一次。 所以request赋值的那个方法,通常是获取页面显示内容的方法。

(7)request的params中,会带多个参数,current当前页,pageSize, name, todo…(打印看看)

(8)补充:ProTable里加: rawKey=“id". 避免了报错:因此每个子项都要有一个key.

4. 搜索功能

(1)函数组件里的ProTable里:search(true)

(2)在columns中某个字段可设置 hideInSearch,来隐藏该字段,使之不作为搜索项。

5. 删除功能

针对接口接收数据的情况的delete操作——这里还未实现,后续在其他文章中会有说明

什么是Promise?

6. 页面分页

data中,加total, pageSize, current

1)mock里的listTavleList.ts:

这里最好用data,不要用别的变量,框架分页所致。如果用别的变量的话,需要额外处理,需要在service.ts中修改。比如用了data1

export default {
  'GET /api/rule': getRule,
  'POST /api/rule': postRule,
  'GET /api/todos': {
    data:[
      {
        id: '001',
        name: 'Kate',
        age: 18,
        todo: '吃饭'
      },
      {
        id: '002',
        name: 'Ellie',
        age: 19,
        todo: '睡觉'
      },
      {
        id: '003',
        name: 'Joe',
        age: 20,
        todo: '上班'
      },
    ],

    total: 101,
    success: true,
    pageSize: "20",
    current: 1
  }
};

处理如下:TodoList里的index.tsx:

request={async (params) => {
    const response = await queryTodos({ ...params })
    console.log(responce)
    return {
        data: response.data1,
        success: response.success,
        total: response.total
    }
  }
}

7.删除?刷新?

在ProTable中加一个actionRef, reload actionRef

8. 测试平台

(1)用例列表(id, casename, method, url...)

        自动化列表

        前后端技术方案,接口约定和定义等等。

        然后分开开发,最后联调起来。

(2)接口列表:

        用例列表

老的风格:

        /api/todos? pageNum=1&cuttent=1&name=123&todo=456 

        GET /api/case/delete?id=3

RESTFUL风格接口:

        POST /api/case/

        DELETE /api/case/3 (数字代表要删哪一个)

接口        名称         path         请求方式         备注

新增         POST      /api/case/                         内容放body

删除         DELETE  /api/case/{id}

修改         PUT         /api/case/{id}                    内容放body

列表查询  GET         /api/cases?…

单条记录查询 GET  /api/case/{id}

(3)定义好接口之后,要开始定义各个接口里的数据个数,现在通常传JSON。

{
        "caseName": "String",
        "method": "POST/GET?DELETE",
        "url": "String",
        "headers": [
                {"key": "key1", "value": "value1"},
                {"key": "key2", "value": "value2"},
                {"key": "key3", "value": "value3"}
        ],
        "body": "String"
}

(4)工具swagger,能根据代码的改动而自动更新接口文档。

即:

在后端修改代码之后,就不用逐个改文档的,它会自动修改(页面上可以查看到)。

实现了在写代码的同时,就把接口文档自动写好了。

用BEJSON页面也可以将JSON转成Java实体类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值