bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

需求分析

需求:(1)在左侧菜单新增自己对应名词的菜单–例: 老师列表-张三(2)添加对应菜单的页面,老师列表页,提供老师信息的查询,新增功能

列表查询页

分两部分:搜索区域(对应参数入参)+列表区域(对应响应参数)
要求:包含参数中要求的控件组件,最终发起请求的参数齐全,响应成功展示正常即可

新增页面

新增页面以弹窗形式完成
要求:包含参数中要求的控件组件,最终发起请求的参数齐全

查询接口

import {addTea, getTeaList} from @/services/ant-design-pro/api ;
addTea为新增老师接口, getTeaList为查询列表接口

查询列表接口参数

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

新增老师接口参数(入参)

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

查询老师列表响应体

{
success:true,
pageSize: 5,
total:100,
data:[
{name:‘张三’,
iPhone:10086,
type:1,
timeList: [1651110000000,1651110314000],
onJob:true,
remarks: “张三是个好老师”
}
], //数组中的对象为Teacher
}

Teacher对象字段

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

新增老师响应体

{
status:200,
}

功能实现

实现新增

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

实现删除/修改、查询

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

实现对列表的搜索查询功能

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

高级表格自带的其它功能

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

例1:

index.tsx页面代码

import React, { useState, useRef } from  react ;
import { PlusOutlined, EllipsisOutlined } from  @ant-design/icons ;
import { Button, message, Menu, Dropdown, Form } from  antd ;
import type { ProColumns, ActionType } from  @ant-design/pro-table ;
import ProTable from  @ant-design/pro-table ;
import request from  umi-request ;
import ProForm, {
  ModalForm,
  ProFormText,
  ProFormTextArea,
  ProFormSelect,
  ProFormDateTimePicker,
} from  @ant-design/pro-form ;
import { useIntl } from  umi ;
import { addTea, getTeaList } from  @/services/ant-design-pro/api ;
import  @ant-design/pro-table/dist/table.css ;
import type { RecordKey } from  @ant-design/pro-utils/lib/useEditableArray ;

const columns: ProColumns<API.teaListItem>[] = [
  {
    dataIndex:  index ,
    valueType:  indexBorder ,
    width: 48,
  },
  {
    title:  名称 ,
    dataIndex:  name ,
    copyable: true,
    ellipsis: true,
    formItemProps: {
    },
  },
  {
    title:  手机号 ,
    dataIndex:  iPhone ,
    copyable: true,
    ellipsis: true,
  },
  {
    disable: true,
    title:  老师类型 ,
    dataIndex:  type ,
    filters: true,
    onFilter: true,
    valueType:  select ,
    valueEnum: {
      0: {
        text:  语文 ,
      },
      1: {
        text:  数学 ,
      },
      2: {
        text:  英语 ,
      },
    },
  },
  {
    disable: true,
    title:  是否在职 ,
    dataIndex:  onJob ,
    filters: true,
    onFilter: true,
    hideInSearch: true,
    valueType:  select ,
    valueEnum: {
      true: {
        text:  是 ,
        status:  Success ,
      },
      false: {
        text:  否 ,
        status:  Error ,
      },
    },
  },
  {
    title:  创建时间 ,
    key:  createTime ,
    dataIndex:  createTime ,
    valueType:  dateTime ,
    sorter: true,
    search: {
      transform: (value) => {
        return {
          createTime: new Date(value).getTime(),
        };
      },
    },
  },
  {
    title:  结束时间 ,
    key:  endTime ,
    dataIndex:  endTime ,
    valueType:  dateTime ,
    sorter: true,
    search: {
      transform: (value) => {
        return {
          endTime: new Date(value).getTime(),
        };
      },
    },
  },
  {
    disable: true,
    title:  备注 ,
    dataIndex:  remarks ,
    search: false,
    renderFormItem: (_, { defaultRender }) => {
      return defaultRender(_);
    },
  },
  {
    title:  操作 ,
    valueType:  option ,
    key:  option ,
    render: (text, record, _, action) => [
      <a
        key="editable"
        onClick={() => {
          action?.startEditable?.(record.key);
        }}
      >
        编辑
      </a>,
    ],
  },
];

const menu = (
  <Menu>
    <Menu.Item key="1">1st item</Menu.Item>
    <Menu.Item key="2">2nd item</Menu.Item>
    <Menu.Item key="3">3rd item</Menu.Item>
  </Menu>
);

/**
 * handleAdd
 * @param fields
 */
const handleAdd = async (fields: API.teaListItem) => {
  const hide = message.loading( 正在添加 );
  // handleList(fields)
  try {
    await addTea({ ...fields });
    hide();
    message.success( Added successfully );
    return true;
  } catch (error) {
    hide();
    message.error( Adding failed, please try again! );
    return false;
  }
};
getTeaList;

const hyhList: React.FC = () => {
  const actionRef = useRef<ActionType>();
  const [createModalVisible, handleModalVisible] = useState<boolean>(false);
  const [form] = Form.useForm();
  const intl = useIntl();
  return (
    <ProTable<API.teaListItem>
      columns={columns}
      actionRef={actionRef}
      cardBordered
      request={async (params = {}, sort, filter) => {
        console.log(sort, filter);
        console.log(params,  ***params );
        let listdata: any;
        listdata = await request<{
          data: API.teaListItem[];
        }>( /api/tea/List , {
          params,
        });
        return Promise.resolve(listdata);
      }}
      editable={{
        type:  multiple ,
        onSave: (key: RecordKey, row: API.teaListItem) => {
          console.log(key, row,  onSave );
          return Promise.resolve();
        },
        onDelete: (key: RecordKey, row: API.teaListItem) => {
          console.log(key, row,  onDelete );
          return Promise.resolve();
        },
      }}
      columnsState={{
        persistenceKey:  pro-table-singe-demos ,
        persistenceType:  localStorage ,
        onChange(value) {
          console.log( value:  , value);
        },
      }}
      rowKey="key"
      search={{
        labelWidth:  auto ,
      }}
      pagination={{
        pageSize: 5,
        onChange: (page) => console.log(page),
      }}
      dateFormatter="string"
      headerTitle="高级表格"
      toolBarRender={() => [
        <Button
          key="button"
          icon={<PlusOutlined />}
          type="primary"
          onClick={() => {
            handleModalVisible(true);
          }}
        >
          新增老师
        </Button>,
        <Dropdown key="menu" overlay={menu}>
          <Button>
            <EllipsisOutlined />
          </Button>
        </Dropdown>,
        <ModalForm
          title={intl.formatMessage({
            id:  pages.searchTable.createForm.newRule ,
            defaultMessage:  New rule ,
          })}
          width="400px"
          visible={createModalVisible}
          onVisibleChange={handleModalVisible}
          form={form}
          onFinish={async (value) => {
            //debugger;
            const success = await handleAdd(value as API.teaListItem);
            if (success) {
              handleModalVisible(false);
              if (actionRef.current) {
                actionRef.current.reload();
                form.resetFields();
              }
            }
          }}
        >
          <ProForm.Group>
            <ProFormText
              width="sm"
              name="name"
              label="老师名称"
              tooltip="最长为 6 位"
              placeholder="请输入老师名称"
            />

            <ProFormText width="sm" name="iPhone" label="手机号码" placeholder="请输入手机号" />
          </ProForm.Group>
          <ProForm.Group>
            <ProFormSelect
              request={async () => [
                {
                  value: 0,
                  label:  数学 ,
                },
                {
                  value: 1,
                  label:  语文 ,
                },
                {
                  value: 2,
                  label:  英语 ,
                },
              ]}
              width="xs"
              name="type"
              label="请选择老师类型"
            />
            <ProFormSelect
              request={async () => [
                {
                  value:  true ,
                  label:  是 ,
                },
                {
                  value:  false ,
                  label:  否 ,
                },
              ]}
              width="xs"
              name="onJob"
              label="请选择是否在任职"
            />
            <ProFormDateTimePicker
              name="createTime"
              label="请选择创建时间"
              transform={(value) => {
                return {
                  createTime: Date.parse(value),
                };
              }}
              rules={[{ required: true, message:  Please select your country!  }]}
            />
            <ProFormDateTimePicker
              name="endTime"
              label="请选择结束时间"
              transform={(value) => {
                return {
                  endTime: Date.parse(value),
                };
              }}
              rules={[{ required: true, message:  Please select your country!  }]}
            />
          </ProForm.Group>
          <ProFormTextArea
            width="md"
            name="remarks"
            label="备注信息"
            placeholder="请输入备注信息"
          />
        </ModalForm>,
      ]}
    />
  );
};
export default hyhList;

api配置

import { request } from  umi ;
import requestumi from  umi-request ;

/** 新增老师 /api/addTea */
export async function addTea(options?: { [key: string]: any }) {
  console.log(options);
  return requestumi<{
    data: [];
  }>( /api/tea/add , {
    method:  POST ,
    params: {
      ...options,
    },
    ...(options || {}),
  });
}

export async function getTeaList(options?: { [key: string]: any }) {
  return requestumi<API.teaListItem>( /api/tea/list , {
    method:  GET ,
    params: {
      ...options,
    },
    ...(options || {}),
  });
}

mock数据处理

import { Request, Response } from  express ;
import { parse } from  url ;

// mock tableListDataSource
const genList = (current: number, pageSize: number) => {
  const tableListDataSource: API.teaListItem[] = [];

  for (let i = 0; i < pageSize; i += 1) {
    const index = (current - 1) * 10 + i;
    tableListDataSource.push({
      key: index,
      onJob: i % 6 === 0,
      name: `张三 ${index}`,
      iPhone: Math.floor(Math.random() * 1000),
      type: i % 3,
      remarks:  这是一段描述 ,
      createTime: new Date().getTime(),
      endTime: new Date().getTime(),
    });
  }
  tableListDataSource.reverse();
  return tableListDataSource;
};

let tableListDataSource = genList(1, 100);

function getTeaList(req: Request, res: Response, u: string) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !==  [object String] ) {
    realUrl = req.url;
  }
  const { current = 1, pageSize = 10 } = req.query;
  const params = parse(realUrl, true).query as unknown as API.PageParams &
    API.teaListItem &
    API.RuleListItem & {
      sorter: any;
      filter: any;
    };

  let dataSource = [...tableListDataSource].slice(
    ((current as number) - 1) * (pageSize as number),
    (current as number) * (pageSize as number),
  );
  if (params.sorter) {
    const sorter = JSON.parse(params.sorter);
    dataSource = dataSource.sort((prev, next) => {
      let sortNumber = 0;
      Object.keys(sorter).forEach((key) => {
        if (sorter[key] ===  descend ) {
          if (prev[key] - next[key] > 0) {
            sortNumber += -1;
          } else {
            sortNumber += 1;
          }
          return;
        }
        if (prev[key] - next[key] > 0) {
          sortNumber += 1;
        } else {
          sortNumber += -1;
        }
      });
      return sortNumber;
    });
  }
  if (params.filter) {
    const filter = JSON.parse(params.filter as any) as {
      [key: string]: string[];
    };
    if (Object.keys(filter).length > 0) {
      dataSource = dataSource.filter((item) => {
        return Object.keys(filter).some((key) => {
          if (!filter[key]) {
            return true;
          }
          if (filter[key].includes(`${item[key]}`)) {
            return true;
          }
          return false;
        });
      });
    }
  }
  //搜索查询
  if (params.name) {
    dataSource = dataSource.filter((data) => data?.name?.includes(params.name ||   ));
  }
  if (params.iPhone) {
    dataSource = dataSource.filter((data) =>
      data?.iPhone?.toString().includes(params.iPhone.toString()),
    );
  }
  if (params.type) {
    dataSource = dataSource.filter((data) =>
      data?.type?.toString().includes(params.type.toString()),
    );
  }
  if (params.createTime) {
    dataSource = dataSource.filter(
      (data) => data?.createTime,
      // data?.createTime >= params.createTime,
    );
  }
  if (params.endTime) {
    dataSource = dataSource.filter(
      (data) => data?.endTime,
      //data?.endTime <= params.endTime,
    );
  }
  const result = {
    data: dataSource,
    total: tableListDataSource.length,
    success: true,
    pageSize,
    current: parseInt(`${params.current}`, 10) || 1,
  };

  return res.json(result);
}

function addTea(req: Request, res: Response, u: string, b: Request) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !==  [object String] ) {
    realUrl = req.url;
  }

  const { pageSize = 1 } = req.query;
  const params = parse(realUrl, true).query as unknown as API.PageParams &
    API.teaListItem &
    API.RuleListItem & {
      sorter: any;
      filter: any;
    };

  let dataSource = [...tableListDataSource];

  for (let i = 0; i < pageSize; i += 1) {
    tableListDataSource.unshift({
      key: tableListDataSource.length,
      onJob: params.onJob,
      name: params.name,
      iPhone: params.iPhone,
      type: params.type,
      remarks: params.remarks,
      createTime: new Date().setTime(params.createTime),
      endTime: new Date().setTime(params.endTime),
    });
  }
  const resultes = {
    data: dataSource,
    total: tableListDataSource.length,
    success: true,
    pageSize,
    current: parseInt(`${params.current}`, 10) || 1,
  };

  return res.json({ status: 200, data: resultes });
}

export default {
   GET /api/tea/List : getTeaList,
   POST /api/tea/add : addTea,
};

typing.d.ts 类型声明文件

declare namespace API {
  type teaListItem = {
    key: index,
    onJob: boolean,
    name: string,
    iPhone: number,
    type: number,
    remarks: string,
    createTime: number,
    endTime: number,
  };
}

proxy.ts文件

export default {
  dev: {
     /api/ : {
      // 要代理的地址
      //target:  https://preview.pro.ant.design ,
      changeOrigin: true,
    },
}};

routes.ts文件

export default [
{
    name:  bunny.list ,
    icon:  table ,
    path:  /hyhList ,
    component:  ./hyhList ,
  },]

menu.ts文件(位置:src/locales/zh-CN/..)

export default {
 menu.bunny.list :  老师列表-bunny ,
}


另一个比较简单的写法,也是实现admin新增页面,实现增删改查的,与上面的相比差一些,可以用作比较,有异同之处。例2:

api-代码

//--查询列表 mock获取-- (ok)
export const getTeaList = async (params: any) => {
  return request( /api/list , { params: params })
}

//--新增老师接口 mock获取--(ok)
export const addTea = async (params: any) => {
  console.log(params);
  return request( /api/add , {
    params: params
  })
}

mock-代码

//方法一:指定给定返回数据的参数
// let list = [
//   {
//     id: 1,
//     name:  bunny ,
//     iPhone:  86688 ,
//     type:  数学 ,
//     createTime: 1650931200000,
//     endTime: 1651276800000,
//     onJob:  true ,
//     remarks:  他是一位好老师 ,
//   },
// ]

//方法二:通过for循环push上去
const genList = (current: number, pageSize: number) => {
  let list = []
  for (let i = 0; i < pageSize; i += 1) {
    const index = (current - 1) * 10 + i;
    list.push({
      id: index,
      onJob: i % 6 === 0,
      name: `bunny ${index}`,
      iPhone: Math.floor(Math.random() * 1000),
      type: i % 3,
      remarks:  描述说明... ,
      createTime: new Date().getTime(),
      endTime: new Date().getTime(),
    });
  }
  list.reverse();
  return list;
};
let list = genList(1, 100);
export default {
   GET /api/list : (req: any, res: any) => {
    let query = req.query;
    //过滤查询
    let dataListSource: any
    function filterQuery(list: any) {
      let dataList: any[] = []
      for (let i in query) {
        let lists = list.filter((item: any) => {
          return item[i] === query[i]
        })
        dataList = [...dataList, ...lists]
        dataListSource = dataList
      }
      res.json({ status: 200, data: Array.from(new Set(dataList)), pageSize: 5, total: list.length })
    }

    if (JSON.stringify(query) ===  {} ) {
      res.json({ status: 200, data: list, pageSize: 5, total: list.length })
    } else {
      //过滤查询
      filterQuery(list)
    }
  },
   GET /api/add : (req: any, res: any) => {
    //添加name
    // console.log(req);
    // res.end( ok )
    // res.end(JSON.stringify(req.body)) //req.body 拿到json数据
    let timeFun = (tiems: string) => {
      let d = new Date(tiems)
      let k = d.getTime()
      console.log(k)
      return k
    }
    const item: any = {
      id: list.length + 1,
      name: req.query.name,
      iPhone: req.query.iPhone,
      type: Number(req.query.type),
      createTime: timeFun(req.query.createTime),
      endTime: timeFun(req.query.endTime),
      onJob: req.query.onJob,
      remarks: req.query.remarks,
    }
    list.unshift(item)
    //list.push(item)
    // res.end({ status: 200 })
    res.json({ status: 200, data: list })
  }
}

index.tsx-代码


import { PlusOutlined, EllipsisOutlined } from  @ant-design/icons ;
import { Button, Menu, Dropdown, message } from  antd ;
import type { ProColumns } from  @ant-design/pro-table ;
import ProTable from  @ant-design/pro-table ;
import { useState, useEffect } from  react ;
import ProForm, {
 ModalForm, ProFormText, ProFormDateRangePicker, ProFormSelect,
} from  @ant-design/pro-form ;
import { addTea, getTeaList } from  @/services/ant-design-pro/api 
import type { RecordKey } from  @ant-design/pro-utils/lib/useEditableArray ;
import request from  umi-request ;

type TeacherIssueItem = {
 name: string;//名称
 iPhone: number;//手机号
 type: number;//老师类型(状态)
 createTime: number;//创建时间
 endTime: number;//结束时间
 onJob: boolean;//是否在职
 remarks: string;//备注
 id: number;
};

const columns: ProColumns<TeacherIssueItem>[] = [
 {
   dataIndex:  index ,
   valueType:  indexBorder ,
   width: 48,
 },
 {
   title:  名 称 ,
   dataIndex:  name ,
   copyable: true,
   ellipsis: true,
 },
 {
   title:  手机号 ,
   dataIndex:  iPhone ,
   copyable: true,
   ellipsis: true,
 },
 {
   disable: true,
   title:  老师类型 ,
   dataIndex:  type ,
   filters: true,
   onFilter: true,
   valueType:  select ,
   valueEnum: {
     all: { text:  全部 , status:  Default  },
     0: {
       text:  语文 ,
     },
     1: {
       text:  数学 ,
     },
     2: {
       text:  英语 ,
     },
   },
 },
 {
   title:  创建时间 ,
   key:  showTime ,
   dataIndex:  createTime ,
   valueType:  dateTime ,
   sorter: true,
   hideInSearch: true,
 },
 {
   title:  创建时间 ,
   dataIndex:  createTime ,
   valueType:  dateRange ,
   hideInTable: true,
   search: {
     transform: (value) => {
       return {
         startTime: value[0],
         endTime: value[1],
       };
     },
   },
 },
 {
   title:  结束时间 ,
   key:  showTime ,
   dataIndex:  endTime ,
   valueType:  dateTime ,
   sorter: true,
   hideInSearch: true,
 },
 {
   title:  结束时间 ,
   dataIndex:  endTime ,
   valueType:  dateRange ,
   hideInTable: true,
   hideInSearch: true,
   search: {
     transform: (value) => {
       return {
         startTime: value[0],
         endTime: value[1],
       };
     },
   },
 },
 {
   disable: true,
   title:  是否在职 ,
   dataIndex:  onJob ,
   filters: true,
   onFilter: true,
   hideInSearch: true,
   valueType:  select ,
   valueEnum: {
     true: {
       text:  是 ,
       status:  Success ,
     },
     false: {
       text:  否 ,
       status:  Error ,
     },
   },
 },
 {
   title:  备 注 ,
   dataIndex:  remarks ,
   hideInSearch: true,
   copyable: true,
   ellipsis: true,
 },
 {
   title:  操作列表 ,
   valueType:  option ,
   key:  option ,
   render: (text, record, _, action) => [
     <a
       key="editable"
       onClick={() => {
         action?.startEditable?.(record.id);
       }}
     >
       编辑
     </a>,
   ],
 },
];

const menu = (
 <Menu>
   <Menu.Item key="1">1st item</Menu.Item>
   <Menu.Item key="2">2nd item</Menu.Item>
   <Menu.Item key="3">3rd item</Menu.Item>
 </Menu>
);

// 数据过滤
function filterData(lists: any) {
 // lists.forEach((ele: any) => {
 //   switch (ele.type) {
 //     case 1:
 //       ele.type =  数学 
 //       break;
 //     case 2:
 //       ele.type =  语文 
 //       break;
 //     case 3:
 //       ele.type =  英语 
 //       break;
 //     case null:
 //       ele.type =  -- 
 //     default:
 //       break;
 //   }
 // })
 return lists
}

export default () => {
 let [list, setList] = useState([]);

 useEffect(async () => {
   if (list.length <= 0) {
     let lists = await getTeaList({})
     setList(filterData(lists.data))
   }
 }, [])

 // //--新增老师数据请求--
 const handleForm = async (values: any) => {
   console.log(values, "values");

   //获取表单新增的数据
   let obj = {
     createTime: values.contractTime ? values.contractTime[0] :  -- ,
     endTime: values.contractTime ? values.contractTime[1] :  -- ,
     name: values.name ? values.name :  -- ,
     type: values.type ? values.type :  -- ,
     iPhone: values.iPhone ? values.iPhone :  -- ,
     onJob: values.onJob ? values.onJob :  -- ,
     remarks: values.remarks ? values.remarks :  -- 
   }

   // 请求获取响应数据,并将新增的数据返回到api接口给后端存储
   const res = await addTea(obj)

   //如果响应状态为200,则是获取成功。添加成功后要刷新列表数据
   if (res.status = 200) {
     //获取最新的列表数据
     let lists = await getTeaList({})
     //将数据更新渲染出来
     setList(filterData(lists.data))
     message.success(res.message)
   } else {
     message.error(res.message)
   }
   return true
 }

 //--添加--搜索
 const beforeSearchSubmit = (val: any) => {
   getTeaList({ ...val }).then((res) => {
     setList(filterData(res.data))
   })
 }
 return (
   <ProTable<TeacherIssueItem>
     columns={columns}
     cardBordered
     dataSource={list}
     // request={ async() =>list}
     // request={async (params) => {
     //   console.log(params, "params");
     //   let data: any
     //   data = await request( /api/List );
     //   console.log(data, "data");//data:[Array]
     //   return Promise.resolve(data);//将列表渲染到页面
     //   // return request<{
     //   // }>( /api/List , {
     //   // }).then((res) => {
     //   //   console.log(res, ".then的res");//data:[Array]
     //   // });
     // }}
     editable={{
       type:  multiple ,
       onSave: (key: RecordKey, row: TeacherIssueItem & {
         index?: number | undefined;
       }) => {
         console.log(key, row,  onSave );
         return Promise.resolve();
       },
       onDelete: (key: RecordKey, row: TeacherIssueItem & {
         index?: number | undefined;
       }
       ) => {
         console.log(key, row,  onDelete );
         return Promise.resolve();
       }
     }}
     columnsState={{
       persistenceKey:  pro-table-singe-demos ,
       persistenceType:  localStorage ,
       onChange(value) {
         console.log( value:  , value);
       },
     }}
     beforeSearchSubmit={beforeSearchSubmit}
     rowKey="id"
     search={{
       labelWidth:  auto ,
     }}
     form={{
       // 由于配置了 transform,提交的参与与定义的不同这里需要转化一下
       syncToUrl: (values, type) => {
         if (type ===  get ) {
           return {
             ...values,
             //开始时间
             createTime: [values.startTime, values.endTime],
           };
         }
         return values;
       },
     }}
     pagination={{
       pageSize: 5,
       onChange: (page) => console.log(page)
       // onChange: onChange,
     }}
     dateFormatter="string"
     headerTitle="高级表格"
     toolBarRender={() => [
       <ModalForm<{
         name: string;
         iPhone: number;
       }>
         title="新增老师"
         trigger={
           <Button key="button" icon={<PlusOutlined />} type="primary">
             新增老师
           </Button>
         }
         autoFocusFirstInput
         modalProps={{
           onCancel: () => console.log( run ),
         }}
         submitTimeout={2000}
         onFinish={value => handleForm(value)}
       >
         <ProForm.Group>
           <ProFormText
             width="sm"
             name="name"
             label="老师名称"
             tooltip="最长为 6 位"
             placeholder="请输入老师名称"
           />

           <ProFormText width="sm" name="iPhone" label="手机号码" placeholder="请输入手机号" />
         </ProForm.Group>
         <ProForm.Group>
           <ProFormSelect
             request={async () => [
               {
                 value: 1,
                 label:  数学 ,
               },
               {
                 value: 2,
                 label:  语文 ,
               },
               {
                 value: 3,
                 label:  英语 ,
               },
             ]}
             width="xs"
             name="type"
             label="请选择老师类型"
           />
           <ProFormSelect
             request={async () => [
               {
                 value:  true ,
                 label:  是 ,
               },
               {
                 value:  false ,
                 label:  否 ,
               }
             ]}
             width="xs"
             name="onJob"
             label="请选择是否在任职"
           />
           <ProFormDateRangePicker name="contractTime" label="请选择起始和结束时间" />
         </ProForm.Group>
         <ProForm.Group>
           <ProFormText width="xl" name="remarks" label="备注信息" placeholder="请输入备注信息" />
         </ProForm.Group>
       </ModalForm>,
       <Dropdown key="menu" overlay={menu}>
         <Button>
           <EllipsisOutlined />
         </Button>
       </Dropdown>,
     ]}
   />
 );
};


其它小知识点的笔记

1. 请求接口,响应数据

(1).then和await的区别:

      request={async (params) => {
        console.log(params, "params");
        return request<{
        }>( /api/List , {
        //  params,//去掉传参
        }).then((res) => {
          console.log(res, ".then的res");
        });
      }}

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

      request={async (params) => {
        console.log(params, "params");
        let data: any
        data = await request( /api/List );
        console.log(data, "data");//data:[Array]
        return Promise.resolve(data);//将列表渲染到页面

        // return request<{
        // }>( /api/List , {
        // }).then((res) => {
        //   console.log(res, ".then的res");
        // });
      }}

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

也可以用表单自带的dataSource来获取请求的数据,如例2里就是这样实现的。

2. 使用antd实现 表单输入完成后重置默认状态(也就是清空原来已经输入的值)

import {  Form } from  antd ;
const hyhList: React.FC = () => {
  const [form] = Form.useForm();//重置表格
  return (
    <ProTable<API.teaListItem>
        <ModalForm
          form={form};//新增
          onFinish={async (value) => {
            if (success) {
                form.resetFields();//重置
              }
            }
         </ModalForm>
     </ProTable>
)
}
export default hyhList;

3. 使用mock转化为时间戳

但是,这样的话,在<ProFormDateTimePicker/>中点击选择时间,得到的时间的的字符串参数就是时间戳格式了。如下图:

    let timeFun = (tiems: string) => {
      let d = new Date(tiems)
      let k = d.getTime()
      console.log(k)
      return k
    }
    const item: any = {
      createTime: timeFun(req.query.createTime),
      endTime: timeFun(req.query.endTime),
    }

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

但列表所得的时间格式是时间戳格式:

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

4.在新增表单中,获取新增数据后转化为时间戳再返回给mock处理时间转化为时间日期格式再返回表单页面

            <ProFormDateTimePicker
              name="createTime"
              label="请选择创建时间"
              transform={(value) => {
                return {
                  createTime: Date.parse(value),
                };
              }}
              rules={[{ required: true, message:  Please select your country!  }]}
            />
            <ProFormDateTimePicker
              name="endTime"
              label="请选择结束时间"
              transform={(value) => {
                return {
                  endTime: Date.parse(value),
                };
              }}
              rules={[{ required: true, message:  Please select your country!  }]}
            />

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

5. ProFormDateTimePicker和 fieldProps的使用

            <ProFormDateTimePicker
              name="createTime"
              label="请选择创建时间"
              fieldProps={{
                format: (value) => value.format( YYYY-MM-DD ),
              }}
              rules={[{ required: true, message:  Please select your country!  }]}
            />
            <ProFormDateTimePicker
              name="endTime"
              label="请选择结束时间"
              fieldProps={{
                format: (value) => value.format( YYYY-MM-DD ),
              }}
              rules={[{ required: true, message:  Please select your country!  }]}
            />

6. index.tsx的页面结构部署

bunny笔记|React+Ant Design pro框架实现Admin页面的功能(新增、删除、修改数据、查询列表等功能),采用mock模拟后端返回的数据处理

7. 编辑的用法,实现删除和保存

{
    title:  操作 ,
    valueType:  option ,
    key:  option ,
    render: (text, record, _, action) => [
      <a
        key="editable"
        onClick={() => {
          action?.startEditable?.(record.key);
        }}
      >
        编辑
      </a>,
    ],
  },

      editable={{
        type:  multiple ,
        onSave: (key: RecordKey, row: API.teaListItem) => {
          console.log(key, row,  onSave );
          return Promise.resolve();
        },
        onDelete: (key: RecordKey, row: API.teaListItem) => {
          console.log(key, row,  onDelete );
          return Promise.resolve();
        },
      }}

8. 想要新增的数据显示在第一条 有两种方式

(1)list.push({
//data数据…
})
list.reverse();
return list;

(2)直接把push()方法 改为 const item={//data数据…} list.unshift(item)

9.Hooks

9.其它嘛,多用多练,多多熟悉吧,一起加油吧~

© 版权声明

相关文章

1 条评论

您必须登录才能参与评论!
立即登录
  • 头像
    YakultDaqi 投稿者

    大佬们分享下完整的代码吗?学习学习

    无记录