Open XJQ124 opened 11 months ago
import React, { useState } from 'react'; import { Button, Form, Input, Popconfirm, Table, Drawer } from 'antd'; const { Search } = Input; //这是Search的回掉函数,接收三个参数,value是输入的文本值,_e表示事件对象(未被使用),info表示搜索的相关信息。 const onSearch = (value, _e, info) => console.log(info?.source, value); //EditableRow组件用于渲染表格的行 //表示从传递给组件的属性中提取 index 属性,并将剩余的属性放入名为 props 的对象中。 //剩余属性语法 ...props 表示将其余的属性收集到一个名为 props 的对象中。 const EditableRow = ({ index, ...props }) => { //创建表单实例 const [form] = Form.useForm(); return ( //将创建的表单实例‘form’绑定 Form 组件上 //component={false} 表示不生成真正的 HTML 表单元素,而只是提供上下文给子组件使用。 <Form form={form} component={false}> {/* 将从父组件传递过来的属性应用到这个表格行上 */} <tr {...props} /> </Form> ); }; //EditableCell组件是表格中每个可编辑单元格的实现。 //它包含了编辑状态的管理、输入框的渲染以及保存编辑后的处理逻辑。 const EditableCell = ({ title, //列标题 editable,//表示该单元格是否可编辑的标志。 children,//单元格中的子元素,通常是显示当前值的内容。 dataIndex,//列在数据源中的索引,用于获取或更新数据源中对应项的值。 record,//表示该行的数据对象,包含了当前单元格所在行的所有数据。 handleSave,//用于保存编辑后数据的回调函数。 ...restProps//包含了除上述属性外的其他属性,将其传递给组件中的其他元素。 }) => { //创建一个editing 的状态变量,用于跟踪当前单元格是否处于编辑状态。 //setEditing 是一个用于更新 editing 状态的函数。 const [editing] = useState(false); //变量初始化,将 childNode 变量初始化为 children,即当前单元格的内容。 let childNode = children; if (editable) { //如果是可编辑的,会出现一个输入框 childNode = editing ? ( <> </> ) : ( <div> </div> ); } return <td {...restProps}>{childNode}</td>; }; const App = () => { //使用useState来创建了一个名为 drawerData 的状态变量,并通过 setDrawerData 函数来更新这个状态。初始状态为{}. //抽屉里的数据 const [drawerData, setDrawerData] = useState({}); //定义抽屉的可见和不可见,默认为不可见 const [drawerVisible, setDrawerVisible] = useState(false); const [count, setCount] = useState(1); //dataSource 通常用于存储表格中的数据。通过 setDataSource 函数,你可以在其他地方更新 dataSource 的内容。 const [dataSource, setDataSource] = useState([]); //编辑函数 const handleEdit = (key) => { // 显示 Drawer setDrawerVisible(true); // 根据 key 获取被编辑行的数据 const editedData = dataSource.filter((item) => item.key === key); // 设置 drawerData 状态为被编辑行的数据 setDrawerData(editedData); // const newData = dataSource.map((item) => { //如果数组中的每个元素的值相同,那么给编辑权限 if (item.key === key) { //...是展开运算符,一般用于展开数组和对象 return { ...item, editing: true }; } return item; }); //更新新的内容 setDataSource(newData); }; //删除部分 const handleDelete = (key) => { //filter 方法用于遍历 dataSource 数组中的每个元素。 //((item) => item.key !== key)是一个过滤条件 const newData = dataSource.filter((item) => item.key !== key); setDataSource(newData); }; //默认的列 const defaultColumns = [ { title: '序号', //dataIndex: 表示该列在数据源中的索引 //即在每个数据项中对应的属性名称。这里是 'name'。 dataIndex: 'number', width: '25%', render: (_, __, index) => index + 1, }, { title: '公司名称', dataIndex: 'name', width: '25%', }, { title: '公司地址', dataIndex: 'address', width: '25%', }, { title: '操作', dataIndex: 'operation', width: '25%', render: (_, record) => ( <div> <Button style={{ marginRight: '5px' }} onClick={() => handleEdit(record.key)} >编辑</Button> <Popconfirm title="确认删除吗?" onConfirm={() => handleDelete(record.key)}> <Button danger>删除</Button> </Popconfirm> </div> ), }, ]; const handleAdd = () => { setDrawerVisible(true); //重置drawerData状态 setDrawerData({}); // setCount(count + 1); } const handleSave = (row) => { //展开原来的DataSource数组,设置为新的newData const newData = [...dataSource]; const index = newData.findIndex((item) => row.key === item.key); if (index !== -1) { const item = newData[index]; //splice是js的数组中的一个方法,用于在数组中添加或者是删除元素 newData.splice(index, 1, { ...item, ...row, }); } else { // 添加新行 newData.push({ key: count, ...row, }); setCount(count + 1); } setDataSource(newData); }; //自带Api const components = { body: { row: EditableRow, cell: EditableCell, }, }; //通过遍历 defaultColumns 数组,生成一个新的 columns 数组。 const columns = defaultColumns.map((col) => { if (!col.editable) { return col; } return { ...col, onCell: (record) => ({ record, editable: col.editable, dataIndex: col.dataIndex, title: col.title, handleSave, }), }; }); return ( <div style={{ padding: '20px' }}> <Button onClick={handleAdd} //按钮类型,是antd的 主按钮 type="primary" style={{ marginBottom: 16, marginRight: '20px' }} > 添加企业用户 </Button> <Search placeholder="查询企业信息" onSearch={onSearch} style={{ width: 200, }} /> <Table //传递了 components 对象 components={components} //为表格的行设置样式类名。 rowClassName={() => 'editable-row'} //显示表格边框。 bordered //表格的数据源,即要展示的数据。 dataSource={dataSource} //表格的列配置 columns={columns} /> <Drawer title="添加企业用户" placement="right" //右侧出现 closable={true} // 是否显示右上角的关闭按钮 onClose={() => setDrawerVisible(false)} visible={drawerVisible} //控制抽屉的可见性,这里使用 drawerVisible 状态来控制。 width={400} > <Form onFinish={(values) => { // 将 values 与 drawerData 合并 const mergedData = { ...drawerData, ...values }; // 使用 handleSave 更新表格数据 handleSave(mergedData); // 隐藏 Drawer setDrawerVisible(false); }} //将抽屉中的数据设置为 drawerData,可以保证每次点击编辑里面有当前行的数据 initialValues={drawerData} > {/* 在这里添加表单字段 */} {/* rules是表单规则,意思是要我们必填,然后显示提示信息 */} <Form.Item label="公司名称" name="name" rules={[{ required: true, message: '请输入公司名称' }]}> <Input /> </Form.Item> <Form.Item label="公司地址" name="address" rules={[{ required: true, message: '请输入公司地址' }]}> <Input /> </Form.Item> {/* 这里的 htmlType="submit"位于 Form 内部时,会触发Form内部的提交 */} <Button type="primary" htmlType="submit"> 提交 </Button> </Form> </Drawer> </div> ); }; export default App;
这个部分相比昨天的内容精简了一些,把不要的代码都删掉了
本来已经把编辑的部分实现了,但是今天修改的过程中又改没了 明天几个任务: 1、实现点击编辑按钮时,Drawer的名称实现改变(目前是显示:添加企业用户) 2、编辑按钮,保存时,自动修改成功(目前是自动增加下一行) 3、新增企业信息时,输入框里原来的内容要消失 4、实现查找功能
完善目前的代码,然后继续学习Ant Design内容(包括其Api和代码)
1、把昨天基于Ant Design的表格的代码看明白了,学习其API,改造自己的代码
这个部分相比昨天的内容精简了一些,把不要的代码都删掉了
2、明日任务:
本来已经把编辑的部分实现了,但是今天修改的过程中又改没了 明天几个任务: 1、实现点击编辑按钮时,Drawer的名称实现改变(目前是显示:添加企业用户) 2、编辑按钮,保存时,自动修改成功(目前是自动增加下一行) 3、新增企业信息时,输入框里原来的内容要消失 4、实现查找功能