当前位置: 首页 > news >正文

2025年07月23日秋瑶传媒一面

目录

  1. react 如何封装一个 table 组件
  2. react 父子组件传值
  3. 讲一下 umi
  4. umi 的状态管理的使用
  5. 介绍下你的项目难点
  6. 讲一下你们小程序是怎么做的
  7. tooltip 组件怎么自定义判断 2 行 3 行的时候展示
  8. umi 怎么动态加载 css js
  9. umi 怎么使用状态管理

1. react 如何封装一个 table 组件

我将为你提供一个封装 Ant Design Table 组件的方案,使其具有类似 Ant Design Pro 的高级功能。这种封装可以提高代码复用性,简化表格使用,并统一项目中的表格风格。

封装思路

我们将创建一个 ProTable 组件,支持以下核心功能:

  • 自动处理分页、排序、筛选
  • 支持搜索表单
  • 集成请求数据的 Hooks
  • 自动生成表格列配置
  • 支持操作栏自定义
  • 统一的样式风格

组件实现

下面是一个完整的 ProTable 组件实现:

import React, { useState, useMemo, useCallback, useEffect } from 'react';
import { Table, Form, Button, Space, Input, Select, Popconfirm } from 'antd';
import { SearchOutlined, ReloadOutlined } from '@ant-design/icons';
import { debounce } from 'lodash';const { Item } = Form;
const { Option } = Select;/*** ProTable 组件 - 封装 Ant Design Table 提供高级功能* @param {Object} props - 组件属性* @param {Array} props.columns - 表格列配置* @param {Function} props.request - 获取数据的请求函数* @param {Object} props.formItems - 搜索表单配置* @param {Object} props.initialValues - 初始表单值* @param {Boolean} props.loading - 加载状态* @param {Function} props.onRow - 行点击事件* @param {Function} props.rowKey - 行键* @param {Object} props.tableProps - 传递给 Table 的其他属性*/
const ProTable = ({columns = [],request,formItems = [],initialValues = {},loading = false,onRow,rowKey = 'id',tableProps = {},
}) => {const [form] = Form.useForm();const [dataSource, setDataSource] = useState([]);const [pagination, setPagination] = useState({current: 1,pageSize: 10,total: 0,});const [sorter, setSorter] = useState({});const [filters, setFilters] = useState({});// 处理搜索表单值变化const handleFormValuesChange = useCallback((changedValues, allValues) => {// 重置分页setPagination(prev => ({...prev,current: 1,}));// 更新筛选条件setFilters(allValues);}, []);// 处理分页变化const handleTableChange = useCallback((pagination, filters, sorter) => {setPagination(pagination);setFilters(filters);setSorter(sorter);}, []);// 构建搜索表单const renderFormItems = useMemo(() => {return formItems.map(item => {const { key, title, type = 'input', options = [], ...rest } = item;switch (type) {case 'select':return (<Item key={key} label={title} name={key} {...rest}><Select placeholder={`请选择${title}`}>{options.map(option => (<Option key={option.value} value={option.value}>{option.label}</Option>))}</Select></Item>);case 'input':default:return (<Item key={key} label={title} name={key} {...rest}><Input placeholder={`请输入${title}`} /></Item>);}});}, [formItems]);// 处理搜索const handleSearch = useCallback(() => {// 重置分页setPagination(prev => ({...prev,current: 1,}));// 触发数据加载fetchData();}, [fetchData]);// 处理重置const handleReset = useCallback(() => {form.resetFields();// 重置分页和筛选setPagination({current: 1,pageSize: 10,total: 0,});setFilters({});setSorter({});// 触发数据加载fetchData();}, [form, fetchData]);// 构建表格列配置const buildColumns = useMemo(() => {return columns.map(column => {// 如果有操作列,添加固定位置if (column.key === 'actions') {return {...column,fixed: 'right',width: 180,};}return column;});}, [columns]);// 合并表格属性const mergedTableProps = useMemo(() => {return {rowKey,dataSource,pagination,loading,onChange: handleTableChange,onRow,columns: buildColumns,...tableProps,};}, [dataSource, pagination, loading, handleTableChange, onRow, buildColumns, tableProps, rowKey]);// 数据加载const fetchData = useCallback(async () => {if (!request) return;try {const { current, pageSize } = pagination;const { field, order } = sorter;const response = await request({page: current,pageSize,sortField: field,sortOrder: order === 'ascend' ? 'asc' : 'desc',...filters,});setDataSource(response.data || []);setPagination(prev => ({...prev,total: response.total || 0,}));} catch (error) {console.error('Failed to fetch data:', error);}}, [request, pagination, sorter, filters]);// 初始化数据useEffect(() => {form.setFieldsValue(initialValues);fetchData();}, [form, initialValues, fetchData]);// 防抖搜索const debouncedSearch = useCallback(debounce(handleSearch, 500),[handleSearch]);return (<div className="pro-table-container">{formItems.length > 0 && (<Formform={form}layout="inline"onValuesChange={handleFormValuesChange}initialValues={initialValues}><div className="pro-table-search-bar"><Space>{renderFormItems}<Item><Button type="primary" onClick={handleSearch} icon={<SearchOutlined />}>搜索</Button></Item><Item><Button onClick={handleReset}>重置</Button></Item></Space></div></Form>)}<Table {...mergedTableProps} /></div>);
};export default ProTable;

使用示例

下面是如何使用这个封装组件的示例:

import React from 'react';
import ProTable from './ProTable';// 模拟API请求
const fetchTableData = async ({ page, pageSize, sortField, sortOrder, ...filters }) => {// 这里应该是实际的API调用console.log('Fetching data with params:', { page, pageSize, sortField, sortOrder, filters });// 模拟返回数据return new Promise(resolve => {setTimeout(() => {resolve({data: [{ id: 1, name: '张三', age: 28, address: '北京市朝阳区', status: 'active' },{ id: 2, name: '李四', age: 32, address: '上海市浦东新区', status: 'inactive' },{ id: 3, name: '王五', age: 45, address: '广州市天河区', status: 'active' },],total: 100,});}, 800);});
};// 表格列配置
const columns = [{title: 'ID',dataIndex: 'id',key: 'id',sorter: true,},{title: '姓名',dataIndex: 'name',key: 'name',sorter: true,},{title: '年龄',dataIndex: 'age',key: 'age',sorter: true,},{title: '地址',dataIndex: 'address',key: 'address',},{title: '状态',dataIndex: 'status',key: 'status',filters: [{ text: '活跃', value: 'active' },{ text: '非活跃', value: 'inactive' },],onFilter: (value, record) => record.status === value,},{title: '操作',key: 'actions',render: (_, record) => (<Space size="small"><a href="#">查看</a><a href="#">编辑</a><Popconfirm title="确定要删除吗?" onConfirm={() => console.log('Delete:', record.id)}><a href="#">删除</a></Popconfirm></Space>),},
];// 搜索表单配置
const formItems = [{key: 'name',title: '姓名',},{key: 'status',title: '状态',type: 'select',options: [{ label: '全部', value: '' },{ label: '活跃', value: 'active' },{ label: '非活跃', value: 'inactive' },],},
];// 页面组件
const MyTablePage = () => {return (<div className="page-container"><h1>用户列表</h1><ProTablecolumns={columns}request={fetchTableData}formItems={formItems}initialValues={{ status: 'active' }}/></div>);
};export default MyTablePage;

样式优化(可选)

添加一些全局样式可以使表格看起来更像 Ant Design Pro:

/* pro-table.css */
.pro-table-container {background-color: #fff;border-radius: 8px;padding: 20px;margin-bottom: 20px;box-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09);
}.pro-table-search-bar {margin-bottom: 16px;padding-bottom: 16px;border-bottom: 1px solid #f0f0f0;
}/* 表格样式优化 */
.ant-table-thead > tr > th {background-color: #fafafa;font-weight: 600;
}.ant-table-tbody > tr:hover > td {background-color: #f5f7fa !important;
}.ant-pagination {margin-top: 16px !important;
}

封装优势

  1. 统一风格:所有表格使用相同的样式和交互逻辑
  2. 简化使用:只需提供列配置和数据请求函数
  3. 自动处理分页/排序/筛选:减少重复代码
  4. 可扩展:可以轻松添加新功能(如导出、批量操作)
  5. 易于维护:一处修改,所有表格生效

你可以根据项目需求进一步扩展这个组件,比如添加批量操作、导出功能、行选择等。

http://www.dtcms.com/a/303140.html

相关文章:

  • 【学习路线】AI开发工程师成长指南:从机器学习基础到大模型应用
  • 调色总监的“色彩炼金术”:在PS中创建LUT,并应用于Premiere Pro视频
  • TCP/IP 网际层详解
  • RCLAMP2574N.TCT Semtech:超低钳位TVS二极管 0.5pF超低电容+±30kV超强防护
  • 【Blender小技巧】Blender使用多边形建形工具创建多边形模型,挤出面,模型创建修改编辑UV贴图
  • PostgreSQL 与 MySQL 时间类型避坑指南
  • 《Ai智能眼镜的市场定义及用户分析》- 深圳市天趣星空科技有限公司 CEO 王洁
  • Java字符串详解
  • Entity Framework Core (EF Core) 使用ado.net
  • 用latex+vscode+ctex写毕业论文
  • Spring源码解读之 JdbcTemplate源码
  • 【基础篇三】WebSocket:实时通信的革命
  • 基于DeepSeek大模型和STM32的矿井“围压-温度-开采扰动“三位一体智能监测系统设计
  • 排序算法 (Sorting Algorithms)-JS示例
  • 安装及使用vscode
  • Unity教程(二十四)技能系统 投剑技能(中)技能变种实现
  • 【Unity游戏】——1.俄罗斯方块
  • Apache Ignite的分布式计算(Distributed Computing)
  • 基于Milvus和BGE-VL模型实现以图搜图
  • 第17章——多元函数积分学的预备知识
  • odoo欧度小程序——修改用户和密码
  • RabbitMQ+内网穿透远程访问教程:实现异地AMQP通信+Web管理
  • 基于springboot的大创管理系统(源码+论文+开题报告)
  • 项目任务如何分配?核心原则
  • 银行个人贷款接受度分析
  • el-upload开启picture形式列表展示上传的非图片文件自定义缩略图
  • 网络层描述
  • Leetcode_349.两个数组的交集
  • Word VBA快速制作试卷(2/2)
  • 【华为机试】5. 最长回文子串