
本文旨在提供一种优化前端导航链接权限控制的方案。通过将权限信息与导航链接配置相结合,并利用用户权限动态过滤导航链接,实现更灵活、可维护的前端权限管理。本文将提供详细的代码示例和步骤,帮助开发者理解和应用该方案。
动态权限控制导航链接的实现
在前端应用中,根据用户权限动态展示导航链接是一种常见的需求。一种有效的实现方式是将权限信息添加到导航链接的配置中,然后在渲染导航链接之前,根据用户的权限对链接进行过滤。
1. 扩展导航链接配置
首先,在你的 links 数组对象中添加一个 roles 字段。这个字段可以是一个角色/权限的字符串,也可以是一个包含多个角色/权限的数组。这些角色/权限应该与后端返回的用户权限对象中的键相匹配。
立即学习“前端免费学习笔记(深入)”;
const links = [
{
id: 1,
text: "panel",
path: "/",
icon: ,
menuItems: ["panel"],
roles: null, // 任何角色/权限都可访问
},
{
id: 2,
text: "employee",
path: ["add-employee", "all-employee"],
icon: ,
menuItems: [
"add new employee",
"all employees",
],
roles: ["addEmployee"], // 仅具有 addEmployee 角色/权限的用户可访问
},
{
id: 3,
text: "customer",
path: ["add-customer", "emp-customers", "all-customers"],
icon: ,
menuItems: [
"add new customer",
"my customers",
"all customers",
],
roles: ["addCustomer", "showAllCustomers"], // 具有 addCustomer 或 showAllCustomers 角色/权限的用户可访问
},
{
id: 4,
text: "报告",
path: ["profile", "aw", "all-jobs", "add-job"],
icon: ,
menuItems: [
"add customer",
"customer Roles",
"all customers",
"الموظف المثالي",
],
roles: ["showAllCustomers"], // 仅具有 showAllCustomers 角色/权限的用户可访问
},
];roles: null 表示该链接对所有用户可见。如果 roles 是一个数组,则表示用户需要拥有数组中至少一个角色/权限才能看到该链接。
2. 过滤导航链接
在映射 links 数组之前,使用 filter 方法根据用户的权限过滤链接。
{links
.filter(link => link.roles?.length
// 如果链接有角色需要检查,则检查用户权限
? link.roles.some(role => user.permissions[role])
// 否则返回 true,包含该菜单链接项
: true
)
.map((link) => {
// ... 渲染链接的代码
})
}这段代码首先检查 link.roles 是否存在且长度大于 0。如果存在,则使用 some 方法检查用户是否拥有 link.roles 数组中的任何一个角色/权限。如果 link.roles 不存在或为空,则直接返回 true,表示该链接对所有用户可见。
3. 完整代码示例
将上述代码片段整合到你的 NavLinks 组件中,最终代码如下:
const NavLinks = ({ ToggleSideBar }) => {
const { user } = useAppContext();
const links = [
{
id: 1,
text: "panel",
path: "/",
icon: ,
menuItems: ["panel"],
roles: null,
},
{
id: 2,
text: "employee",
path: ["add-employee", "all-employee"],
icon: ,
menuItems: [
"add new employee",
"all employees",
],
roles: ["addEmployee"],
},
{
id: 3,
text: "customer",
path: ["add-customer", "emp-customers", "all-customers"],
icon: ,
menuItems: [
"add new customer",
"my customers",
"all customers",
],
roles: ["addCustomer", "showAllCustomers"],
},
{
id: 4,
text: "报告",
path: ["profile", "aw", "all-jobs", "add-job"],
icon: ,
menuItems: [
"add customer",
"customer Roles",
"all customers",
"الموظف المثالي",
],
roles: ["showAllCustomers"],
},
];
const [isDropdownOpen2, setIsDropdownOpen2] = useState(false);
const [isDropdownOpen3, setIsDropdownOpen3] = useState(false);
const toggleDropdown2 = () => {
setIsDropdownOpen2(!isDropdownOpen2);
};
const toggleDropdown3 = () => {
setIsDropdownOpen3(!isDropdownOpen3);
};
const [activeStatus, setActiveStatus] = useState({
firstnavcontainer: false,
secondnavcontainer: false,
thirdnavcontainer: false,
});
const firstFunction = () => {
setActiveStatus((prevState) => ({
firstnavcontainer: true,
secondnavcontainer: false,
thirdnavcontainer: false,
}));
};
const secondFunction = () => {
setActiveStatus((prevState) => ({
...prevState,
firstnavcontainer: false,
secondnavcontainer: true,
thirdnavcontainer: false,
}));
console.log(activeStatus);
};
const thirdFunction = () => {
setActiveStatus((prevState) => ({
...prevState,
firstnavcontainer: false,
secondnavcontainer: false,
thirdnavcontainer: true,
}));
};
return (
{links
.filter(link => link.roles?.length
? link.roles.some(role => user.permissions[role])
: true
)
.map((link) => {
const { text, path, id, icon, menuItems } = link;
return (
<>
{/* first item */}
{id === 1 && (
{menuItems.map((item, index) => (
isActive
? "dropdownmenu-item red-background"
: "dropdownmenu-item"
}
>
{item}
))}
)}
{/* second section */}
{id === 2 && (
{isDropdownOpen2 && (
{menuItems.map((item, index) => (
isActive
? "dropdownmenu-item active"
: "dropdownmenu-item"
}
>
{item}
))}
)}
)}
{/* third section */}
{id === 3 && (
{isDropdownOpen3 && (
{menuItems.map((item, index) => (
isActive
? "dropdownmenu-item active"
: "dropdownmenu-item"
}
>
{item}
))}
)}
)}
>
);
})}
);
};
export default NavLinks;注意事项
- 确保后端返回的用户权限对象与 links 数组中 roles 字段的值保持一致。
- user.permissions 对象应该是一个包含布尔值的对象,例如:{ addCustomer: true, editAndDeleteCustomer: false, ... }。
- 这种方法可以灵活地控制导航链接的可见性,并且易于维护和扩展。
总结
通过将权限信息添加到导航链接的配置中,并利用用户权限动态过滤导航链接,可以实现更灵活、可维护的前端权限管理。这种方法不仅可以控制导航链接的可见性,还可以轻松地扩展到其他需要权限控制的组件中。









