antd专门为react定制的中后台组件库,提供了大量的组件供开发者使用,
官网地址 点击跳转
在中后台中,用户管理是必不可少的。外部用户和内部用户的管理,都涉及到用户、角色和权限的管理。
用户管理贯穿业务各个环节,是支撑业务运营的核心部分。
今天就使用react结合antd V5.0 处理一下用户管理.
此用户管理,分为以下部分:
- 用户列表 – 展示用户
- 用户添加
- 用户删除
- 用户信息更新
- 用户查询/筛选
本节主要是阐述如何配置用户展示、用户添加、用户删除。
此部分,主要用到了antd的组件如下:
- Space
- Switch,
- Table,
- Modal,
- Tag,
- Button
展示用户列表
实现步骤如下:
第一步,获取用户数据用于渲染表格
此部分用到 表格 组件.
选用的是 树形数据展示 ,当然也可以选择其他。
获取数据
const [dataSource, setdataSource] = useState([]);
useEffect(() => {
const fetchGetUserListHandle = async () => {
const urseListData = await fetchGetUserList();
setdataSource(urseListData);
};
fetchGetUserListHandle();
}, []);
渲染表格
<Table
dataSource={dataSource}
columns={columns}
rowKey={(item) => item.id}
pagination={{
pageSize: 5,
}}
></Table>
请注意此处的表格分页设置
显示
pagination={{
pageSize: 5,
}}
更多设置,请参考pagination
第二步,表格添加自定义渲染设置
列描述数据对象 – render,是 columns 中的一项,Column 使用相同的 API。
render 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引 、
使用方法: function(text, record, index) {}
此部分,不在赘述,可以查看前面的文章,传送门。
页面显示如下
添加用户
添加用户比较复杂,所以,添加用户抽离除了一个组件。
添加用户使用的是antd的表单 – 弹出层中的新建表单组件。
此部分涉及到父子组件交互,所以,比较繁琐。
官网案例实现代码如下:
import { Button, Form, Input, Modal, Radio } from 'antd';
import { useState } from 'react';
const CollectionCreateForm = ({ open, onCreate, onCancel }) => {
const [form] = Form.useForm();
return (
<Modal
open={open}
title="Create a new collection"
okText="Create"
cancelText="Cancel"
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="title"
label="Title"
rules={[
{
required: true,
message: 'Please input the title of collection!',
},
]}
>
<Input />
</Form.Item>
<Form.Item name="description" label="Description">
<Input type="textarea" />
</Form.Item>
<Form.Item name="modifier" className="collection-create-form_last-form-item">
<Radio.Group>
<Radio value="public">Public</Radio>
<Radio value="private">Private</Radio>
</Radio.Group>
</Form.Item>
</Form>
</Modal>
);
};
const App = () => {
const [open, setOpen] = useState(false);
const onCreate = (values) => {
console.log('Received values of form: ', values);
setOpen(false);
};
return (
<div>
<Button
type="primary"
onClick={() => {
setOpen(true);
}}
>
New Collection
</Button>
<CollectionCreateForm
open={open}
onCreate={onCreate}
onCancel={() => {
setOpen(false);
}}
/>
</div>
);
};
export default App;
实现步骤如下:
第一步 新建AddUserForm
文件作为添加用户的组件,并引入到页面。
import React, { useEffect, useRef, useState } from "react";import {
DeleteOutlined,
EditOutlined,
ExclamationCircleFilled,
} from "@ant-design/icons";
import AddUserModal from "./AddUserForm"; // 引用组件
import {
fetchGetRegionList,
fetchGetRoles,
fetchAddUser
} from "../../utils/api"; // 引用api
// 添加用户处理
const [open, setOpen] = useState(false);
const [regionList, setregionList] = useState([]);
const [rolesList, serolesList] = useState([]);
const AddUserFormData = useRef(null);
// 获取用户数据处理
useEffect(() => {
// 获取用户数据处理
const fetchGetRegionListHandle = async () => {
const urseListData = await fetchGetRegionList();
setregionList(urseListData);
};
fetchGetRegionListHandle();
// 获取用户数据处理
const fetchGetRolesListHandle = async () => {
const urseListData = await fetchGetRoles();
serolesList(urseListData);
};
fetchGetRolesListHandle();
}, []);
const onCreate = async (values) => {
setOpen(false);
//post到后端,生成id,再设置 datasource, 方便后面的删除和更新
const data = await fetchAddUser({
...values,
roleState: true,
default: false,
});
setdataSource([
...dataSource,
{
...data,
role: rolesList.filter((item) => item.id === values.roleId)[0],
},
]);
};
// 页面中引用
<AddUserModal
open={open}
onCreate={onCreate}
onCancel={() => {
setOpen(false);
}}
regionList={regionList}
rolesList={rolesList}
ref={AddUserFormData}
></AddUserModal>
特别注意,为了方便使用form属性值,此处用了react useRef
hooks
useRef的介绍
useRef返回一个可变的ref对象,该对象只有个current属性,初始值为传入的数(initialValue)
可以获得某个dom节点的引用,保证获取到的数据肯定是最新的。并且ref在组件内任何地方内都可以访问到,类似组件内的全局变量
第二步,添加用户表单设计与实现
此部分需要注意:
- forwardRef hooks写法
- forwardRef 参数问题,即传递
ref
forwardRef(({}, ref)=>{
... do something
})
上例中,{}为props值。
- 重置属性setFieldsValue的使用
ref.current.setFieldsValue({
region:""
})
"./AddUserForm"代码如下
import { forwardRef, useState } from "react";
import { Form, Input, Modal, Radio, Select } from "antd";
// 注意此处 forwardRef写法
const AddUserModal = forwardRef(
({ open, onCreate, onCancel, regionList, rolesList }, ref) => { // 注意此处参数设置: {}, ref
const [regionDisable, setregionDisable] = useState(false)
return (
<div>
<Modal
open={open}
title="添加用户"
okText="确定"
cancelText="取消"
onCancel={onCancel}
onOk={() => {
ref.current.validateFields()
.then((values) => {
console.log(values)
onCreate(values);
ref.current.resetFields();
})
.catch((info) => {
console.log("Validate Failed:", info);
});
}}
>
<Form
ref={ref}
layout="vertical"
name="form_in_modal"
initialValues={{
modifier: "public",
}}
>
<Form.Item
name="username"
label="用户名"
rules={[
{
required: true,
message: "Please input the title of collection!",
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="password"
label="密码"
rules={[
{
required: true,
message: "Please input the title of collection!",
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="roleId"
label="角色"
rules={ [
{
required: true,
message: "Please input the title of collection!",
},
]}
>
<Select onChange={(value)=>{
if(value === 1){
setregionDisable(true)
ref.current.setFieldsValue({
region:""
})
}else{
setregionDisable(false)
}
}}>
{rolesList.map((item) => (
<Select.Option value={item.id} key={item.id}>
{item.roleName}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item
name="region"
label="部门"
rules={regionDisable ? [] :[
{
required: true,
message: "Please input the title of collection!",
},
]}
>
<Select disabled={regionDisable}>
{regionList.map((item) => (
<Select.Option value={item.value} key={item.id}>
{item.title}
</Select.Option>
))}
</Select>
</Form.Item>
</Form>
</Modal>
</div>
);
}
);
export default AddUserModal;
页面显示如下
删除用户
删除操作
删除操作是一个比较危险的操作,所以,需要再次提醒用户是否确实需要删除操作。
此处使用了 弹出确认框组件
// 删除弹框事件
const confirmHandel = (item) => {
confirm({
title: "您确定要删除吗?",
icon: <ExclamationCircleFilled />,
content: "此处删除会删除用户,请谨慎操作!",
okText: "确认",
cancelText: "取消",
onOk() {
console.log("OK");
deleteRolesMethod(item);
},
onCancel() {
console.log("Cancel");
},
});
};
// 删除事件
const deleteRolesMethod = async (item) => {
setdataSource(dataSource.filter((data) => data.id != item.id));
const data = await fetchDeleteUser(item.id);
};
完整代码
UserList.js
import React, { useEffect, useRef, useState } from "react";
import { Space, Switch, Table, Modal, Tag, Button } from "antd";
import {
DeleteOutlined,
EditOutlined,
ExclamationCircleFilled,
} from "@ant-design/icons";
import AddUserModal from "./AddUserForm";
import {
fetchGetUserList,
fetchGetRegionList,
fetchGetRoles,
fetchAddUser,
fetchDeleteUser,
} from "../../utils/api";
const { confirm } = Modal;
export default function UserList() {
const [dataSource, setdataSource] = useState([]);
const columns = [
{
title: "部门",
dataIndex: "region",
render: (region) => {
return region === "" ? "总部" : region;
},
},
{
title: "角色名称",
dataIndex: "role",
render: (role) => {
return <Tag color="magenta">{role?.roleName}</Tag>;
},
},
{
title: "用户名",
dataIndex: "username",
},
{
title: "用户状态",
dataIndex: "roleState",
render: (roleState, item) => {
// 注意这里
return (
<div>
<Switch size="small" checked={roleState} disabled={item.default} />
</div>
);
},
},
{
title: "操作",
render: (item) => {
return (
<Space>
<Button
icon={<EditOutlined style={{ fontSize: "12px" }} />}
shape="circle"
type="primary"
size="small"
// onClick={() => showModal(item)}
></Button>
<Button
icon={<DeleteOutlined style={{ fontSize: "12px" }} />}
shape="circle"
danger
size="small"
onClick={() => {
confirmHandel(item);
}}
></Button>
</Space>
);
},
},
];
// 获取用户数据处理
useEffect(() => {
const fetchGetUserListHandle = async () => {
const urseListData = await fetchGetUserList();
setdataSource(urseListData);
};
fetchGetUserListHandle();
}, []);
// 添加用户处理
const [open, setOpen] = useState(false);
const [regionList, setregionList] = useState([]);
const [rolesList, serolesList] = useState([]);
const AddUserFormData = useRef(null);
// 获取用户数据处理
useEffect(() => {
// 获取用户数据处理
const fetchGetRegionListHandle = async () => {
const urseListData = await fetchGetRegionList();
setregionList(urseListData);
};
fetchGetRegionListHandle();
// 获取用户数据处理
const fetchGetRolesListHandle = async () => {
const urseListData = await fetchGetRoles();
serolesList(urseListData);
};
fetchGetRolesListHandle();
}, []);
const onCreate = async (values) => {
console.log("Received values of form: ", values);
setOpen(false);
//post到后端,生成id,再设置 datasource, 方便后面的删除和更新
const data = await fetchAddUser({
...values,
roleState: true,
default: false,
});
setdataSource([
...dataSource,
{
...data,
role: rolesList.filter((item) => item.id === values.roleId)[0],
},
]);
};
// 删除弹框事件
const confirmHandel = (item) => {
confirm({
title: "您确定要删除吗?",
icon: <ExclamationCircleFilled />,
content: "此处删除会删除用户,请谨慎操作!",
okText: "确认",
cancelText: "取消",
onOk() {
console.log("OK");
deleteRolesMethod(item);
},
onCancel() {
console.log("Cancel");
},
});
};
// 删除事件
const deleteRolesMethod = async (item) => {
console.log(item);
setdataSource(dataSource.filter((data) => data.id != item.id));
const data = await fetchDeleteUser(item.id);
};
return (
<div>
<div style={{ padding: "0 0 20px 0" }}>
<Button
size="small"
type="primary"
onClick={() => {
setOpen(true);
console.log(AddUserFormData);
}}
>
添加用户
</Button>
</div>
<Table
dataSource={dataSource}
columns={columns}
rowKey={(item) => item.id}
pagination={{
pageSize: 5,
}}
></Table>
<AddUserModal
open={open}
onCreate={onCreate}
onCancel={() => {
setOpen(false);
}}
regionList={regionList}
rolesList={rolesList}
ref={AddUserFormData}
></AddUserModal>
</div>
);
}
“./AddUserForm”
import { forwardRef, useState } from "react";
import { Form, Input, Modal, Radio, Select } from "antd";
const AddUserModal = forwardRef(
({ open, onCreate, onCancel, regionList, rolesList }, ref) => {
const [regionDisable, setregionDisable] = useState(false)
return (
<div>
<Modal
open={open}
title="添加用户"
okText="确定"
cancelText="取消"
onCancel={onCancel}
onOk={() => {
ref.current.validateFields()
.then((values) => {
console.log(values)
onCreate(values);
ref.current.resetFields();
})
.catch((info) => {
console.log("Validate Failed:", info);
});
}}
>
<Form
ref={ref}
layout="vertical"
name="form_in_modal"
initialValues={{
modifier: "public",
}}
>
<Form.Item
name="username"
label="用户名"
rules={[
{
required: true,
message: "Please input the title of collection!",
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="password"
label="密码"
rules={[
{
required: true,
message: "Please input the title of collection!",
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="roleId"
label="角色"
rules={ [
{
required: true,
message: "Please input the title of collection!",
},
]}
>
<Select onChange={(value)=>{
if(value === 1){
setregionDisable(true)
ref.current.setFieldsValue({
region:""
})
}else{
setregionDisable(false)
}
}}>
{rolesList.map((item) => (
<Select.Option value={item.id} key={item.id}>
{item.roleName}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item
name="region"
label="部门"
rules={regionDisable ? [] :[
{
required: true,
message: "Please input the title of collection!",
},
]}
>
<Select disabled={regionDisable}>
{regionList.map((item) => (
<Select.Option value={item.value} key={item.id}>
{item.title}
</Select.Option>
))}
</Select>
</Form.Item>
</Form>
</Modal>
</div>
);
}
);
export default AddUserModal;