日常的crud页面分为筛选、表格、分页
使用react和antd快速搭建页面,只需简单配置json即可
对按钮级别进行二次封装,主要是点击弹出modal
里面是常见add,delete,edit三种按钮进行弹窗封装
ini
import { Button, Modal } from "antd";
import React, { useState } from "react";
type XtButtonProps = {
type: string;
onOk: () => void;
getRowData?: any;
className?: string;
children?: React.ReactNode;
};
const XtButton: React.FC<XtButtonProps> = ({ type, onOk, getRowData, children, className, ...rest }) => {
const [modalVisible, setModalVisible] = useState(false);
const handleCloseModal = () => {
setModalVisible(false);
};
const handleOpenModal = () => {
getRowData();
setModalVisible(true);
};
const handleOk = () => {
onOk();
setModalVisible(false);
};
const handleDelete = () => {
Modal.confirm({
title: "Delete Item",
content: "Are you sure you want to delete this item?",
onOk: handleOk,
onCancel: handleCloseModal
});
};
return (
<>
{type === "delete" ? (
<Button className={className} onClick={handleDelete}>
Delete
</Button>
) : (
<Button className={className} type="primary" onClick={handleOpenModal}>
{type === "add" ? "Add" : "Edit"}
</Button>
)}
{type !== "delete" && (
<Modal
visible={modalVisible}
onOk={handleOk}
onCancel={handleCloseModal}
title={type === "add" ? "Add Item" : "Edit Item"}
{...rest}
>
{children}
</Modal>
)}
</>
);
};
export default XtButton;
然后是table的二次封装,主要二次封装是获取数据加载loading
typescript
import { Table } from "antd";
import React, { useEffect, useState } from "react";
type XtTableProps = {
columns: any;
dataSource: any;
getData: () => void;
};
const XtTable: React.FC<XtTableProps> = ({ columns, dataSource, getData, ...rest }) => {
const [loading, setLoading] = useState(true);
// 获取table数据
const getTableData = async () => {
setLoading(true);
getData();
setLoading(false);
};
useEffect(() => {
getTableData();
}, []);
return (
<>
<Table columns={columns} dataSource={dataSource} loading={loading} rowKey="id" {...rest} />
</>
);
};
export default XtTable;
其次就是弹窗组件的children的组件封装,这里是模仿table的columns的json配置进行一个form封装,render方法是进行一个子组件的渲染
typescript
import React from "react";
type DynamicFormProps = {
columns: any[]; // 配置数组
width?: string;
};
const DynamicForm: React.FC<DynamicFormProps> = ({ columns, width = "80px" }) => {
return (
<div>
{columns.map((item: any) => (
<div key={item.title} className="flex-ct" style={{ marginBottom: "16px" }}>
<div style={{ width: width, marginRight: "16px" }}>{item.title}:</div>
<div style={{ flex: 1 }}>{item.render()}</div>
</div>
))}
</div>
);
};
export default DynamicForm;
封装的form组件,可以渲染Input、select等组件 ,具体的可以在render里面去配置
typescript
import DynamicForm from "@/components/DynamicForm";
import XtSelect from "@/components/Select";
import { Input } from "antd";
import React from "react";
type FormProps = {
data: any;
setData: any;
};
const roleList = ["超级管理员", "客户"];
const form: React.FC<FormProps> = ({ data, setData }) => {
const { account, password, role, devices } = data;
const columns = [
{
title: "account",
render: () => <Input value={account} onChange={e => handleChange(e.target.value, "account")}></Input>
},
{
title: "password",
render: () => <Input value={password} onChange={e => handleChange(e.target.value, "password")}></Input>
},
{
title: "role",
render: () => <XtSelect options={roleList} value={role} onChange={e => handleChange(e, "role")} />
},
{
title: "devices",
render: () => <XtSelect mode="multiple" options={roleList} value={devices} onChange={e => handleChange(e, "devices")} />
}
];
const handleChange = (e: any, field: string) => {
setData((prevData: any) => ({
...prevData,
[field]: e
}));
console.log("🚀 ~ file: form.tsx:37 ~ handleChange ~ e:", e);
};
return <DynamicForm columns={columns} />;
};
export default form;
遇到crud页面,就只需要配置table的json、筛选项以及modal的form,就可以快速生成页面进行接口联调,当然这个是比较通用的,筛选项等都是自己后续去书写,如果你的项目有其他的需求可以按照这个去再进行封装