参考项目:https://github.com/marmelab/react-admin
技术栈:
React 全家桶
步骤一:安装
1、创建项目npm create react-admin@latest my-admin -- --template simple
这一命令会下载 React Admin 的简单模板,包含 Vite 作为构建工具和 TypeScript
2、安装 Mock 数据支持npm install ra-data-json-server
这个包帮助 React Admin 与简单的 REST API(比如 json-server)通信。
3、创建一个 db.json 文件(在根目录创建),用于存储 Mock 数据
这是模拟的后端数据,users 提供用户列表,dashboard 提供仪表盘统计
{
"users": [
{ "id": 1, "name": "张三", "age": 32, "address": "北京" },
{ "id": 2, "name": "李四", "age": 28, "address": "上海" }
],
"dashboard": {
"id": 1,
"userCount": 1000,
"orderCount": 500,
"salesData": [
{ "day": "Mon", "value": 150 },
{ "day": "Tue", "value": 230 }
]
}
}
4、全局安装 json-server npm install -g json-server
新开一个窗口运行:json-server --watch db.json --port 3001
步骤二:配置 Data Provider 也就是数据来源。参考: https://marmelab.com/react-admin/DataProviders.html
1、根目录创建dataProvider.ts
// 配置 React Admin 的 dataProvider,让前端知道如何从 Mock API 获取数据。
import { fetchUtils } from "react-admin";
import DataProvider from "ra-data-json-server";
const httpClient = (url: string, options: any = {}) => {
if (!options.headers) {
options.headers = new Headers({ Accept: "application/json" });
}
return fetchUtils.fetchJson(url, options);
};
export const dataProvider = DataProvider("/api", httpClient);
2、修改主应用文件 src/App.tsx
import { Admin, Resource } from "react-admin";
import { dataProvider } from "../dataProvider";
import { Dashboard } from "./pages/Dashboard";
import { UserList } from "./pages/UserList";
import { CustomLayout } from "./components/Layout";
const App = () => (
<Admin dataProvider={dataProvider} layout={CustomLayout}>
<Resource name="users" list={UserList} />
<Resource name="dashboard" list={Dashboard} />
</Admin>
);
export default App;
dataProvider 告诉 React Admin 从哪里获取数据。
<Resource> 定义了两个资源:users(用户列表)和 dashboard(仪表盘)。
CustomLayout 稍后会创建,用于自定义界面布局。
步骤三:创建自定义布局
1、在 src 目录下,新建文件夹 components
,然后新建文件 Layout.tsx
// Copyright (c) 2025 zdb
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
import { Layout, LayoutProps } from "react-admin";
import { AppBar, Toolbar, Typography, CssBaseline } from "@mui/material";
import { MySidebar } from "../components/MySidebar";
export const CustomLayout = (props: LayoutProps) => {
// 类型保护,确保 children 存在
if (!props.children) return null;
return (
<>
<CssBaseline />
<div style={{ display: "flex", width: "100%" }}>
<Layout>
<MySidebar {...props}></MySidebar>
<div style={{ flexGrow: 1 }}>
<AppBar position="static" color="primary">
<Toolbar>
<Typography variant="h6" style={{ color: "white" }}>
后台管理系统
</Typography>
</Toolbar>
</AppBar>
<main style={{ padding: 16 }}>{props.children}</main>
</div>
</Layout>
</div>
</>
);
};
2、继续创建MySidebar.tsx
// Copyright (c) 2025 zdb
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
import { Drawer } from "@mui/material";
import { SidebarClasses, useLocale, useSidebarState } from "react-admin";
export const MySidebar = ({ children }: any) => {
const [open, setOpen] = useSidebarState();
useLocale(); // force redraw on locale change
const toggleSidebar = () => setOpen(!open);
return (
<Drawer
variant="temporary"
open={open}
onClose={toggleSidebar}
classes={SidebarClasses}
>
{children}
</Drawer>
);
};
注意: Material-UI 的样式可能需要调整,可以在 index.css 中添加全局样式。
3、创建 Dashboard.tsx
(src/pages
)
// Copyright (c) 2025 zdb
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
import { useDataProvider } from "react-admin";
import { useEffect, useState } from "react";
import { Card, CardContent, Typography } from "@mui/material";
export const Dashboard = () => {
const dataProvider = useDataProvider();
const [data, setData] = useState({
userCount: 0,
orderCount: 0,
salesData: [],
});
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
console.log("Fetching dashboard data");
let mounted = true;
setIsLoading(true); // 开始加载
const fetchData = async () => {
try {
const { data: responseData } = await dataProvider.getOne("dashboard", {
id: "1",
});
if (mounted) setData(responseData);
} catch (error) {
console.error("Error fetching dashboard data:", error);
} finally {
if (mounted) setIsLoading(false);
}
};
fetchData();
return () => {
mounted = false;
}; // 清理
}, []); // 空依赖数组
if (isLoading) return <div>Loading...</div>;
return (
<div>
<Card>
<CardContent>
<Typography variant="h5">仪表盘</Typography>
<Typography>用户数量: {data.userCount}</Typography>
<Typography>订单数量: {data.orderCount}</Typography>
</CardContent>
</Card>
</div>
);
};
useDataProvider 从 Mock API 获取 dashboard 数据,useEffect 确保页面加载时请求数据。
4、创建UserList.tsx
(src/UserList.tsx
)
// Copyright (c) 2025 zdb
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
import {
List,
Datagrid,
TextField,
EditButton,
DeleteButton,
} from "react-admin";
export const UserList = () => (
<List>
<Datagrid>
<TextField source="id" />
<TextField source="name" />
<TextField source="age" />
<TextField source="address" />
<EditButton />
<DeleteButton />
</Datagrid>
</List>
);