react antd快速搭建crud页面

日常的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,就可以快速生成页面进行接口联调,当然这个是比较通用的,筛选项等都是自己后续去书写,如果你的项目有其他的需求可以按照这个去再进行封装

相关推荐
再吃一根胡萝卜10 分钟前
Vue + dompdf.js 实现简历分页导出的完整踩坑记录
前端
其美杰布-富贵-李23 分钟前
第 6 篇:相机与 OrbitControls
前端·javascript·three.js
lichenyang45327 分钟前
从图片生成任务到用户隔离:AIGC Creative Studio 后端与 PostgreSQL 建模实践
前端·后端
小黑技术栈1 小时前
关于前端的一些话
前端
无人生还1 小时前
从 Vue3 到 React · 快速上手系列第 11 篇:状态管理
前端·vue.js·react.js
GuWenyue1 小时前
90%前端写React TS都踩坑!一套父子组件+Hooks完整实战,彻底搞懂类型约束
前端·react.js
Hilaku2 小时前
当 AI 一天写完一周的代码,我们还剩什么优势?
前端·javascript·程序员
尘世中一位迷途小书童2 小时前
无人机航线里的云台角度怎么调?Cesium 做了个视锥 + 鹰眼联动
前端·javascript·数据可视化
思码梁田2 小时前
CSS display 属性:从元素类型转换到隐藏元素的实用指南
前端·css·display·inline·block·none·inline-block
Csvn2 小时前
⚡ Vite 依赖预构建(optimizeDeps)的 3 个经典坑:改了源码不生效、新增依赖 404、缓存怎么清都不行
前端