antd专门为react定制的中后台组件库,提供了大量的组件供开发者使用,
官网地址 点击跳转
在中后台中,权限管理是必不可少的,今天就使用react结合antd V5.0 处理一下权限管理.
此权限管理,分两部分: 权限列表和角色管理。
- 权限列表即如何
在页面中配置左侧导航栏显示列表
- 角色管理即各种
用户角色配置
本节主要是阐述如何配置权限列表。
最终显示结果如下:
此部分,主要用到了antd的组件如下:
- Space,
- Switch,
- Table,
- Tag,
- Button,
- Modal,
- Popover
实现步骤如下:
第一步,获取左侧导航数据用于渲染表格
此部分用到表格组件.
选用的是 树形数据展示 ,当然也可以选择其他。
获取数据
const [dataSource, setdataSource] = useState([]);
useEffect(() => {
const fetchData = async () => {
const menusListData = await fetchGetMenus(); // fetchGetMenus 为获取导航数据的api接口
menusListData.forEach((element) => {
if (element.children.length === 0) {
element.children = ""; // 此处处理是为了防止有空数组显示
}
});
setdataSource(menusListData);
};
fetchData();
}, []);
渲染表格
// RightList.js
import { useState, useEffect } from 'react'
import {Table} from "antd";
export default function Redirect() {
const [dataSource, setdataSource] = useState([]);
useEffect(() => {
const fetchData = async () => {
const menusListData = await fetchGetMenus(); // fetchGetMenus 为获取导航数据的api接口
menusListData.forEach((element) => {
if (element.children.length === 0) {
element.children = ""; // 此处处理是为了防止有空数组显示
}
});
setdataSource(menusListData);
};
fetchData();
}, []);
const columns = [
{
title: "ID",
dataIndex: "id",
},
{
title: "权限名称",
dataIndex: "title",
},
{
title: "权限路径",
dataIndex: "key"
},
];
return (
<div>Redirect</div>
)
}
页面显示如下
第二步,表格添加自定义渲染设置
列描述数据对象 – render,是 columns 中的一项,Column 使用相同的 API。
render 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引 、
使用方法: function(text, record, index) {}
改造columns数据
// RightList.js
const columns = [
{
title: "ID",
dataIndex: "id",
},
{
title: "权限名称",
dataIndex: "title",
},
{
title: "权限路径",
dataIndex: "key",
render: (key) => {
return <Tag color="magenta">{key}</Tag>;
},
},
{
title: "操作",
render: (item) => { // 注意此处传值 item
// item
return (
<Space>
<Popover
style={{ width: "100px" }}
content={
<div
style={{
display: "flex",
alignItems: "center",
textAlign: "center",
}}
>
<h5 style={{padding: '0 10px 0 0'}}>显示左侧导航栏</h5>{" "}
<Switch
size="small"
checked={item.pagepermisson === 1 ? true : false}
onChange={() => switchChange(item)}
/>
</div>
}
title="左侧导航栏权限配置"
trigger={item.pagepermisson === undefined ? "" : "click"}
>
<Button
icon={<EditOutlined style={{ fontSize: "12px" }} />}
shape="circle"
type="primary"
size="small"
disabled={item.pagepermisson === undefined}
></Button>
</Popover>
<Button
icon={<DeleteOutlined style={{ fontSize: "12px" }} />}
shape="circle"
danger
size="small"
onClick={() => {
confirmHandel(item); // 注意此处传值 item
}}
></Button>
</Space>
);
},
},
];
页面展示如下
第三步,添加编辑和删除事件
删除操作
删除操作是一个比较危险的操作,所以,需要再次提醒用户是否确实需要删除操作。
此处使用了 弹出确认框组件
// 删除弹框事件
const confirmHandel = (item) => {
confirm({
title: "您确定要删除吗?",
icon: <ExclamationCircleFilled />,
content: "此处删除会删除掉左侧导航,请谨慎操作!",
okText: "确认",
cancelText: "取消",
onOk() {
console.log("OK");
deleteRightMethod(item);
},
onCancel() {
console.log("Cancel");
},
});
};
// 删除事件
const deleteRightMethod = async (item) => {
console.log(item);
if (item.grade === 1) {
setdataSource(dataSource.filter((data) => data.id != item.id));
const menusListData = await fetchDeleteMenus(item.id); // 调用后端接口
} else if (item.grade === 2) {
let list = dataSource.filter((data) => data.id === item.rightId);
list[0].children = list[0].children.filter((data) => data.id !== item.id);
setdataSource([...dataSource]);
const menusListData = await fetchDeleteSubMenus(item.id); // 调用后端接口
} else {
return false;
}
};
编辑操作
// 编辑事件
const switchChange = async (item) => {
console.log(item);
item.pagepermisson = item.pagepermisson === 1 ? 0 : 1;
setdataSource([...dataSource]);
if (item.grade === 1) {
await fetchPatchMenus(item.id, { pagepermisson: item.pagepermisson }); // 调用后端接口
} else if (item.grade === 2) {
await fetchPatchSubMenus(item.id, { pagepermisson: item.pagepermisson }); // 调用后端接口
} else {
return false;
}
};
完整代码
import { useState, useEffect } from "react";
import { Space, Switch, Table, Tag, Button, Modal, Popover } from "antd";
import {
DeleteOutlined,
EditOutlined,
ExclamationCircleFilled,
} from "@ant-design/icons";
import {
fetchGetMenus,
fetchDeleteMenus,
fetchDeleteSubMenus,
fetchPatchMenus,
fetchPatchSubMenus,
} from "../../utils/api";
const { confirm } = Modal;
export default function RightList() {
const [dataSource, setdataSource] = useState([]);
useEffect(() => {
const fetchData = async () => {
const menusListData = await fetchGetMenus();
menusListData.forEach((element) => {
if (element.children.length === 0) {
element.children = "";
}
});
setdataSource(menusListData);
};
fetchData();
}, []);
// 删除弹框事件
const confirmHandel = (item) => {
confirm({
title: "您确定要删除吗?",
icon: <ExclamationCircleFilled />,
content: "此处删除会删除掉左侧导航,请谨慎操作!",
okText: "确认",
cancelText: "取消",
onOk() {
console.log("OK");
deleteRightMethod(item);
},
onCancel() {
console.log("Cancel");
},
});
};
// 删除事件
const deleteRightMethod = async (item) => {
console.log(item);
if (item.grade === 1) {
setdataSource(dataSource.filter((data) => data.id != item.id));
const menusListData = await fetchDeleteMenus(item.id);
} else if (item.grade === 2) {
let list = dataSource.filter((data) => data.id === item.rightId);
list[0].children = list[0].children.filter((data) => data.id !== item.id);
setdataSource([...dataSource]);
const menusListData = await fetchDeleteSubMenus(item.id);
} else {
return false;
}
};
// 编辑事件
const switchChange = async (item) => {
console.log(item);
item.pagepermisson = item.pagepermisson === 1 ? 0 : 1;
setdataSource([...dataSource]);
if (item.grade === 1) {
await fetchPatchMenus(item.id, { pagepermisson: item.pagepermisson });
} else if (item.grade === 2) {
await fetchPatchSubMenus(item.id, { pagepermisson: item.pagepermisson });
} else {
return false;
}
};
const columns = [
{
title: "ID",
dataIndex: "id",
},
{
title: "权限名称",
dataIndex: "title",
},
{
title: "权限路径",
dataIndex: "key",
render: (key) => {
return <Tag color="magenta">{key}</Tag>;
},
},
{
title: "操作",
render: (item) => {
// item
return (
<Space>
<Popover
style={{ width: "100px" }}
content={
<div
style={{
display: "flex",
alignItems: "center",
textAlign: "center",
}}
>
<h5 style={{padding: '0 10px 0 0'}}>显示左侧导航栏</h5>{" "}
<Switch
size="small"
checked={item.pagepermisson === 1 ? true : false}
onChange={() => switchChange(item)}
/>
</div>
}
title="左侧导航栏权限配置"
trigger={item.pagepermisson === undefined ? "" : "click"}
>
<Button
icon={<EditOutlined style={{ fontSize: "12px" }} />}
shape="circle"
type="primary"
size="small"
disabled={item.pagepermisson === undefined}
></Button>
</Popover>
<Button
icon={<DeleteOutlined style={{ fontSize: "12px" }} />}
shape="circle"
danger
size="small"
onClick={() => {
confirmHandel(item);
}}
></Button>
</Space>
);
},
},
];
return (
<div>
<Table columns={columns} dataSource={dataSource} />
</div>
);
}
需要思考问题
- 如何自定义渲染表格,即添加操作一列?
- 是否所有的权限都可以编辑?
- 为什么需要刷新页面,左侧导航呈现修改状态?
- 是否还有需要完善部分?肯定有。如何完善?
此问题,下部分在做回答。