
本文旨在提供一种优化前端导航链接权限控制的方案。通过将权限信息与导航链接配置相结合,并利用用户权限动态过滤导航链接,实现更灵活、可维护的前端权限管理。本文将提供详细的代码示例和步骤,帮助开发者理解和应用该方案。
在前端应用中,根据用户权限动态展示导航链接是一种常见的需求。一种有效的实现方式是将权限信息添加到导航链接的配置中,然后在渲染导航链接之前,根据用户的权限对链接进行过滤。
1. 扩展导航链接配置
首先,在你的 links 数组对象中添加一个 roles 字段。这个字段可以是一个角色/权限的字符串,也可以是一个包含多个角色/权限的数组。这些角色/权限应该与后端返回的用户权限对象中的键相匹配。
立即学习“前端免费学习笔记(深入)”;
const links = [
{
id: 1,
text: "panel",
path: "/",
icon: <IoBarChartSharp />,
menuItems: ["panel"],
roles: null, // 任何角色/权限都可访问
},
{
id: 2,
text: "employee",
path: ["add-employee", "all-employee"],
icon: <MdQueryStats />,
menuItems: [
"add new employee",
"all employees",
],
roles: ["addEmployee"], // 仅具有 addEmployee 角色/权限的用户可访问
},
{
id: 3,
text: "customer",
path: ["add-customer", "emp-customers", "all-customers"],
icon: <FaWpforms />,
menuItems: [
"add new customer",
"my customers",
"all customers",
],
roles: ["addCustomer", "showAllCustomers"], // 具有 addCustomer 或 showAllCustomers 角色/权限的用户可访问
},
{
id: 4,
text: "报告",
path: ["profile", "aw", "all-jobs", "add-job"],
icon: <ImProfile />,
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: <IoBarChartSharp />,
menuItems: ["panel"],
roles: null,
},
{
id: 2,
text: "employee",
path: ["add-employee", "all-employee"],
icon: <MdQueryStats />,
menuItems: [
"add new employee",
"all employees",
],
roles: ["addEmployee"],
},
{
id: 3,
text: "customer",
path: ["add-customer", "emp-customers", "all-customers"],
icon: <FaWpforms />,
menuItems: [
"add new customer",
"my customers",
"all customers",
],
roles: ["addCustomer", "showAllCustomers"],
},
{
id: 4,
text: "报告",
path: ["profile", "aw", "all-jobs", "add-job"],
icon: <ImProfile />,
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 (
<div className="nav-links">
{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 && (
<div className="nav-item extra" onClick={firstFunction}>
<ul className="dropdown-menu">
{menuItems.map((item, index) => (
<NavLink
to={path[index]}
// onClick={ToggleSideBar}
className={({ isActive }) =>
isActive
? "dropdownmenu-item red-background"
: "dropdownmenu-item"
}
>
<div className="dropdown-itemcontainer">
<span className="dropdown-itemtext">{item}</span>
</div>
</NavLink>
))}
</ul>
</div>
)}
{/* second section */}
{id === 2 && (
<div className="nav-item extra" onClick={secondFunction}>
<button
className={`dropdown-toggle ${
activeStatus.secondnavcontainer ? "red-background" : ""
}`}
>
<div className="dropdownbtn">
<span className="icon">{icon}</span>
<span>{text}</span>
</div>
<BsChevronDown
className="dropdown-icon"
onClick={toggleDropdown2}
/>
</button>
{isDropdownOpen2 && (
<ul className="dropdown-menu">
{menuItems.map((item, index) => (
<NavLink
to={path[index]}
// onClick={ToggleSideBar}
className={({ isActive }) =>
isActive
? "dropdownmenu-item active"
: "dropdownmenu-item"
}
>
<div className="dropdown-itemcontainer">
<span className="dropdown-itemtext">{item}</span>
</div>
</NavLink>
))}
</ul>
)}
</div>
)}
{/* third section */}
{id === 3 && (
<div className="nav-item extra" onClick={thirdFunction}>
<button
className={`dropdown-toggle ${
activeStatus.thirdnavcontainer ? "red-background" : ""
}`}
>
<div className="dropdownbtn">
<span className="icon">{icon}</span>
<span>{text}</span>
</div>
<BsChevronDown
className="dropdown-icon"
onClick={toggleDropdown3}
/>
</button>
{isDropdownOpen3 && (
<ul className="dropdown-menu">
{menuItems.map((item, index) => (
<NavLink
to={path[index]}
// onClick={ToggleSideBar}
className={({ isActive }) =>
isActive
? "dropdownmenu-item active"
: "dropdownmenu-item"
}
>
<div className="dropdown-itemcontainer">
<span className="dropdown-itemtext">{item}</span>
</div>
</NavLink>
))}
</ul>
)}
</div>
)}
</>
);
})}
</div>
);
};
export default NavLinks;注意事项
总结
通过将权限信息添加到导航链接的配置中,并利用用户权限动态过滤导航链接,可以实现更灵活、可维护的前端权限管理。这种方法不仅可以控制导航链接的可见性,还可以轻松地扩展到其他需要权限控制的组件中。
以上就是前端权限控制优化:动态渲染导航链接的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号