Antd 是一个很优秀的组件库
这篇文章使用 Antd 的 Model 组件和 Table 组件,实现对表格的增删操作。
首先来看一个基本的 Table 组件
import React from 'react'
import { Table } from 'antd'
// 数据源 ===> 一般都是从后端提供的接口中获取数据
const dataSource = [
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
];
// 展示在页面上的列数项,有几个对象,就有几列
const columns = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
];
const City = () => {
return (
<Table dataSource={dataSource} columns={columns} />
)
}
export default City
但是光有数据展示还不够,我们希望可以对数据进行点击选择操作
Table
组件上有一个 rowSelection
属性上的 onChange 事件,可以监听到每一次点击选择的表格项。
import React, { useState } from 'react'
import { Table } from 'antd';
// 数据源 ===> 一般都是从后端提供的接口中获取数据
const dataSource = [
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
];
// 展示在页面上的列数项,有几个对象,就有几列
const columns = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
];
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
},
};
const City = () => {
const [selectionType, setSelectionType] = useState('checkbox');
return (
<div>
<Table
rowSelection={{
type: selectionType,
...rowSelection,
}}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default City
得到了相对应的表格列表项之后,就可以请求后端的删除数据接口,对选中的数据进行删除。当然,删除数据是一项很危险的操作,我们有必要在真正删除之前提示操作者。
添加 Model 框提示,在操作者点击确认按钮时,进行真正的删除操作。
import React, { useState } from 'react'
import { Table, Modal } from 'antd';
const City = () => {
const [selectionType, setSelectionType] = useState('checkbox');
const [isModalVisible, setIsModalVisible] = useState(false);
const [selectedData, setSelectedData] = useState([])
const showModal = () => {
setIsModalVisible(true);
};
const handleOk = () => {
console.log('selectedData', selectedData)
// 获取数据,进行删除操作
setIsModalVisible(false);
};
const handleCancel = () => {
setIsModalVisible(false);
};
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
setSelectedData(selectedRows)
showModal()
},
};
return (
<div>
<Table
rowSelection={{
type: selectionType,
...rowSelection,
}}
columns={columns}
dataSource={dataSource}
/>
<Modal title="删除确认框" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
<h1>确认是否删除?</h1>
</Modal>
</div>
);
}
export default City
当数据过多时,需要进行分页操作。
PS:应该是我自身的问题,我不太清楚怎么通过 table 自带的分页去获取对应的页码数。所以我选择了使用 Antd 中 Pagination 组件
通过 Pagination 组件上的 onChange 事件,监听 pagination 的数字变化
import React, { useState, useEffect } from 'react'
import { Table, Modal, Pagination } from 'antd';
const City = () => {
const [selectionType, setSelectionType] = useState('checkbox');
const [isModalVisible, setIsModalVisible] = useState(false);
const [selectedData, setSelectedData] = useState([])
const [pagination, setPagination] = useState(1)
const showModal = () => {
setIsModalVisible(true);
};
const handleOk = () => {
console.log('selectedData', selectedData)
// 获取数据,进行删除操作
setIsModalVisible(false);
};
const handleCancel = () => {
setIsModalVisible(false);
};
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
setSelectedData(selectedRows)
showModal()
},
};
const paginationChange = (pagination) => {
console.log(pagination)
setPagination(pagination)
}
useEffect(() => {
// 请求函数
requestList(pagination)
}, [pagination])
return (
<div>
<Table
rowSelection={{
type: selectionType,
...rowSelection,
}}
pagination={false}
columns={columns}
dataSource={dataSource}
/>
<Pagination onChange={paginationChange} defaultCurrent={1} total={50} />
<Modal title="删除确认框" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
<h1>确认是否删除?</h1>
</Modal>
</div>
);
}
export default City
到此一步,基本的数据展示与数据删除就可以了。
接下来添加按钮,用于实现 model 框的显示与隐藏,同时进行组件的封装,将添加信息的组件封装在一起。
import React, { useState, useEffect } from 'react'
import { Table, Modal, Pagination, Button, Form, Select, Input} from 'antd';
const City = () => {
const [visible, setVisible] = useState(false)
const handleClick = () => {
setVisible(true)
}
const onCreate = (values) => {
setVisible(false);
}
return (
<div>
<Button type="primary" onClick={handleClick}>添加信息</Button>
<Table
rowSelection={{
type: selectionType,
...rowSelection,
}}
pagination={false}
columns={columns}
dataSource={dataSource}
/>
<Pagination onChange={paginationChange} defaultCurrent={1} total={50} />
<Modal title="删除确认框" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
<h1>确认是否删除?</h1>
</Modal>
<Information
visible={visible}
onCreate={onCreate}
onCancel={() => {
setVisible(false);
}}
/>
</div>
);
}
const Information = ({ visible, onCreate, onCancel }) => {
const [form] = Form.useForm()
return (
<Modal
visible={visible}
okText="确认"
cancelText="取消"
onCancel={onCancel}
onOk={() => {
form
.validateFields()
.then((values) => {
form.resetFields();
onCreate(values);
})
.catch((info) => {
console.log('Validate Failed:', info);
});
}}
>
<p>model</p>
</Modal>
)
}
export default City
在 model
框中填入 form
表单,model 框中的 onCreate 函数可以接收填写的内容。
// export default City
import React, { useState, useEffect } from 'react'
import { Table, Modal, Pagination, Button, Form, Select, Input } from 'antd';
const City = () => {
const [visible, setVisible] = useState(false)
const handleClick = () => {
setVisible(true)
}
const onCreate = (values) => {
console.log('onCreate', values)
setVisible(false);
}
return (
<div>
<Button type="primary" onClick={handleClick}>添加信息</Button>
<Table
rowSelection={{
type: selectionType,
...rowSelection,
}}
pagination={false}
columns={columns}
dataSource={dataSource}
/>
<Pagination onChange={paginationChange} defaultCurrent={1} total={50} />
<Modal title="删除确认框" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
<h1>确认是否删除?</h1>
</Modal>
<Information
visible={visible}
onCreate={onCreate}
onCancel={() => {
setVisible(false);
}}
/>
</div>
);
}
const Information = ({ visible, onCreate, onCancel }) => {
const [form] = Form.useForm()
return (
<Modal
visible={visible}
okText="确认"
cancelText="取消"
onCancel={onCancel}
onOk={() => {
form
.validateFields()
.then((values) => {
form.resetFields();
onCreate(values);
})
.catch((info) => {
console.log('Validate Failed:', info);
});
}}
>
<Form
form={form}
layout="vertical"
name="form_in_modal"
initialValues={{
modifier: 'public',
}}
>
<Form.Item
name="id"
label="选择城市"
rules={[
{
required: true,
message: '请选择',
},
]}
>
<Select style={{ width: 100 }}>
<Select.Option value={12443}>洛阳市</Select.Option>
<Select.Option value={11443}>北京市</Select.Option>
</Select>
</Form.Item>
<Form.Item
name="franchisee_name"
label="授权加盟商"
rules={[
{
required: true,
message: '请选择',
},
]}
>
<Input type="text" placeholder="请输入姓名" />
</Form.Item>
</Form>
</Modal>
)
}
export default City
可以在 onCreate 函数请求后端的接口,将填写的数据保存在数据库中。
import React, { useState, useEffect } from 'react'
import { Card, Button, Table, Form, Select, Modal, Input, message, Pagination } from 'antd'
import axios from '../../axios/index'
import Utils from '../../utils/utils'
const FormItem = Form.Item
const Option = Select.Option
const City = () => {
const [visible, setVisible] = useState(false)
const [list, setList] = useState([])
const [pagination, setPagination] = useState(1)
const [selectedRowKeys, setSelectedRowKeys] = useState([])
const [isModalVisible, setIsModalVisible] = useState(false)
const onCreate = (values) => {
let sys_user_name = JSON.parse(localStorage.getItem('bikeCMS'))
setVisible(false);
axios.ajax({
url: '/city/openCity',
data: {
params: {
sys_user_name,
...values
}
}
}).then((res) => {
if (res.status === 200 && res.code === 0) {
message.info(res.result);
requestList()
}
})
}
const requestList = (pagination) => {
axios.ajax({
url: '/city/list',
data: {
params: {
page: pagination
}
}
}).then((res) => {
let list = res.result.item_list.map((item, index) => {
item.key = index;
return item;
});
setList(list)
})
}
useEffect(() => {
requestList(pagination)
}, [pagination])
const columns = [
{
title: '城市ID',
dataIndex: 'id'
}, {
title: '城市名称',
dataIndex: 'name'
}, {
title: '用车模式',
dataIndex: 'mode',
render(mode) {
return mode === 1 ? '停车点' : '禁停区';
}
}, {
title: '营运模式',
dataIndex: 'op_mode',
render(op_mode) {
return op_mode === 1 ? '自营' : '加盟';
}
}, {
title: '授权加盟商',
dataIndex: 'franchisee_name'
}, {
title: '城市管理员',
dataIndex: 'city_admins',
render(arr) {
return arr.map((item) => {
return item;
}).join(' , ');
}
}, {
title: '城市开通时间',
dataIndex: 'open_time',
render: Utils.formateDate
}, {
title: '操作时间',
dataIndex: 'update_time',
render: Utils.formateDate
}, {
title: '操作人',
dataIndex: 'sys_user_name'
}
]
const onSelectChange = (selectedRowKeys) => {
console.log('selectedRowKeys changed: ', selectedRowKeys);
setSelectedRowKeys(selectedRowKeys)
showModal()
};
const rowSelection = {
selectedRowKeys,
onChange: onSelectChange,
};
const paginationChange = (pagination) => {
setPagination(pagination)
}
const showModal = () => {
setIsModalVisible(true);
};
const handleOk = () => {
let delDataId = list[selectedRowKeys]
console.log(delDataId)
setIsModalVisible(false);
};
const handleCancel = () => {
setIsModalVisible(false);
};
return (
<div style={{ width: '100%' }}>
<Card style={{ marginTop: 10, paddingTop: 15 }}>
<Button
type="primary"
onClick={() => {
setVisible(true);
}}
>
开通城市
</Button>
</Card>
<Card>
<div className="content-wrap">
<Table
bordered
columns={columns}
dataSource={list}
pagination={false}
rowSelection={rowSelection}
/>
<div className="pagination" style={{ float: 'right', marginTop: 20 }}>
<Pagination onChange={paginationChange} defaultCurrent={1} total={10 * (pagination + 1)} />
</div>
</div>
</Card>
<Modal visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
<p>确认删除?</p>
</Modal>
<OpenCity
visible={visible}
onCreate={onCreate}
onCancel={() => {
setVisible(false);
}}
/>
</div>
)
}
const OpenCity = ({ visible, onCreate, onCancel }) => {
const [form] = Form.useForm()
return (
<Modal
visible={visible}
title="开通城市"
okText="确认"
cancelText="取消"
onCancel={onCancel}
onOk={() => {
form
.validateFields()
.then((values) => {
form.resetFields();
onCreate(values);
})
.catch((info) => {
console.log('Validate Failed:', info);
});
}}
>
<Form
form={form}
layout="vertical"
name="form_in_modal"
initialValues={{
modifier: 'public',
}}
>
<Form.Item
name="id"
label="选择城市"
rules={[
{
required: true,
message: '请选择',
},
]}
>
<Select style={{ width: 100 }}>
<Option value={12443}>洛阳市</Option>
<Option value={11443}>北京市</Option>
<Option value={14644}>厦门市</Option>
<Option value={14643}>广州市</Option>
<Option value={14443}>深圳市</Option>
<Option value={14244}>柳州市</Option>
<Option value={84244}>合肥市</Option>
<Option value={74244}>南昌市</Option>
<Option value={45244}>大同市</Option>
</Select>
</Form.Item>
<Form.Item
name="op_mode"
label="营运模式"
rules={[
{
required: true,
message: '请选择',
},
]}>
<Select style={{ width: 100 }}>
<Option value={1}>自营</Option>
<Option value={2}>加盟</Option>
</Select>
</Form.Item>
<Form.Item
name="mode"
label="用车模式"
rules={[
{
required: true,
message: '请选择',
},
]}
>
<Select style={{ width: 100 }}>
<Option value={1}>指定停车点</Option>
<Option value={2}>禁停区</Option>
</Select>
</Form.Item>
<Form.Item
name="franchisee_name"
label="授权加盟商"
rules={[
{
required: true,
message: '请选择',
},
]}
>
<Input type="text" placeholder="请输入姓名" />
</Form.Item>
<Form.Item
name="city_admins"
label="城市管理员"
rules={[
{
required: true,
message: '请选择',
},
]}
>
<Input type="text" placeholder="请输入姓名" />
</Form.Item>
</Form>
</Modal>
)
}
export default City
文章的代码有点多,都是可以直接复制粘贴看效果的。对于管理系统而言,无非都是一些表格的显示与操作。使用 UI 组件库,可以大大减少开发的时间,还是蛮方便的。
:木兰君 / 共享单车后台管理系统
获取 react + antd 实战视频资料(回复共享单车后台管理系统)