User页面渲染

Tutorial: ReactTS案例 Category: React Published: 2026-04-07 13:58:26 Views: 20 Likes: 0 Comments: 0

新建 User 页面, 并渲染

  1. 样式 src\pages\user\user.module.scss
.userContainer {
  border: 1px solid red;
}
  1. 全局参数类型声明 src\pages\user\user.d.ts
declare interface User {
  id: number;
  username: string;
  password: string;
  email: string;
}
  1. 页面部署 src\pages\user\index.tsx
import React, { useRef, useState } from "react";
import { Table, Button, Space, Input } from "antd";
import type { InputRef } from "antd";
import { SearchOutlined, SyncOutlined } from "@ant-design/icons";
import type { ColumnsType, ColumnType } from "antd/es/table";
import type { FilterConfirmProps } from "antd/es/table/interface";
import Highlighter from "react-highlight-words";
import styles from "./user.module.scss";

type DataIndex = keyof User;

const Index = () => {
  const [searchText, setSearchText] = useState("");
  const [searchedColumn, setSearchedColumn] = useState("");
  const searchInput = useRef<InputRef>(null);

  const handleSearch = (
    selectedKeys: string[],
    confirm: (param?: FilterConfirmProps) => void,
    dataIndex: DataIndex
  ) => {
    confirm();
    setSearchText(selectedKeys[0]);
    setSearchedColumn(dataIndex);
  };

  const handleReset = (clearFilters: () => void) => {
    clearFilters();
    setSearchText("");
  };

  const getColumnSearchProps = (dataIndex: DataIndex): ColumnType<User> => ({
    filterDropdown: ({
      setSelectedKeys,
      selectedKeys,
      confirm,
      clearFilters,
      close,
    }) => (
      <div style={{ padding: 8 }} onKeyDown={(e) => e.stopPropagation()}>
        <Input
          ref={searchInput}
          placeholder={`Search ${dataIndex}`}
          value={selectedKeys[0]}
          onChange={(e) =>
            setSelectedKeys(e.target.value ? [e.target.value] : [])
          }
          onPressEnter={() =>
            handleSearch(selectedKeys as string[], confirm, dataIndex)
          }
          style={{ marginBottom: 8, display: "block" }}
        />
        <Space>
          <Button
            type="primary"
            size="small"
            onClick={() =>
              handleSearch(selectedKeys as string[], confirm, dataIndex)
            }
            icon={<SearchOutlined />}
          >
            搜索
          </Button>
          <Button
            type="primary"
            size="small"
            onClick={() => {
              clearFilters && handleReset(clearFilters);
              confirm({ closeDropdown: true });
              close();
            }}
            icon={<SyncOutlined />}
          >
            还原
          </Button>
        </Space>
      </div>
    ),
    filterIcon: (filtered: boolean) => (
      <SearchOutlined style={{ color: filtered ? "#1890ff" : undefined }} />
    ),
    onFilter: (value, record) =>
      record[dataIndex]
        .toString()
        .toLowerCase()
        .includes((value as string).toLowerCase()),
    onFilterDropdownOpenChange: (visible) => {
      if (visible) {
        setTimeout(() => searchInput.current?.select(), 100);
      }
    },
    render: (text) =>
      searchedColumn === dataIndex ? (
        <Highlighter
          highlightStyle={{ backgroundColor: "#ffc069", padding: 0 }}
          searchWords={[searchText]}
          autoEscape
          textToHighlight={text ? text.toString() : ""}
        />
      ) : (
        text
      ),
  });

  const dataSource: User[] = [
    {
      id: 1,
      username: "user1",
      password: "pwd123",
      email: "123456@qq.com",
    },
    {
      id: 2,
      username: "user2",
      password: "pwd123",
      email: "123456@qq.com",
    },
    {
      id: 3,
      username: "user2",
      password: "pwd123",
      email: "123456@qq.com",
    },
    {
      id: 4,
      username: "user4",
      password: "pwd123",
      email: "123456@qq.com",
    },
    {
      id: 5,
      username: "user5",
      password: "pwd123",
      email: "123456@qq.com",
    },
    {
      id: 6,
      username: "user6",
      password: "pwd123",
      email: "123456@qq.com",
    },
    {
      id: 7,
      username: "user7",
      password: "pwd123",
      email: "123456@qq.com",
    },
    {
      id: 8,
      username: "user8",
      password: "pwd123",
      email: "123456@qq.com",
    },
    {
      id: 9,
      username: "user9",
      password: "pwd123",
      email: "123456@qq.com",
    },
    {
      id: 10,
      username: "user10",
      password: "pwd123",
      email: "123456@qq.com",
    },
    {
      id: 11,
      username: "user11",
      password: "pwd123",
      email: "123456@qq.com",
    },
  ];

  const columns: ColumnsType<User> = [
    {
      title: "ID",
      width: 100,
      dataIndex: "id",
      key: "id",
      align: "center",
      fixed: "left",
    },
    {
      title: "姓名",
      dataIndex: "username",
      key: "username",
      ...getColumnSearchProps("username"),
    },
    {
      title: "email",
      dataIndex: "email",
      key: "email",
    },
    {
      title: "操作",
      key: "operation",
      fixed: "right",
      width: 160,
      align: "center",
      render(value, record, index) {
        return (
          <Space>
            <Button type="primary">编辑</Button>
            <Button type="primary">删除</Button>
          </Space>
        );
      },
    },
  ];

  return (
    <div className={styles.userContainer}>
      <Button style={{ float: "right" }} type="primary">
        新增
      </Button>
      <Table
        rowKey={"id"}
        dataSource={dataSource}
        columns={columns}
        scroll={{ x: 1500, y: 500 }}
      />
    </div>
  );
};

export default Index;
  1. App.tsx 引入
import React from "react";
import { Routes, Route } from "react-router-dom";

import DashBoard from "./pages/dashBoard"; // 提前创建好
import Login from "./pages/login";
import User from "./pages/user";

function App() {
  return (
    <>
      <Routes>
        <Route path="/" element={<DashBoard />} />
        <Route path="/login" element={<Login />} />
        <Route path="/user" element={<User />} />
      </Routes>
    </>
  );
}

export default App;