React admin后台管理系统(一)
39

参考项目: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.tsxsrc/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.tsxsrc/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>
);

React admin后台管理系统(一)
https://zdbxll.cn/archives/1750412247871
作者
Administrator
发布于
更新于
许可