设计思路
- 基于装饰器的权限控制:利用TypeScript装饰器,在组件定义阶段添加权限控制逻辑,使得代码具有声明式的特点,提高代码的可读性和可维护性。
- 性能优化:避免在每个渲染周期都进行权限检查,通过缓存权限判断结果的方式,减少不必要的重复计算。
- 代码复用:将权限检查逻辑抽象成通用的装饰器,不同组件通过复用装饰器实现权限控制。
- 与React Router兼容性:结合React Router的路由配置,在路由切换时进行权限检查,确保用户只能访问有权限的页面。
关键代码实现
- 定义权限类型:
type Permission = 'admin' | 'user' | 'guest';
- 创建权限检查装饰器:
import { ComponentClass } from'react';
const withPermission = (requiredPermission: Permission) => {
return (WrappedComponent: ComponentClass) => {
const cache: { [key: string]: boolean } = {};
return class extends React.Component {
constructor(props: any) {
super(props);
const userPermission = getCurrentUserPermission(); // 假设该函数获取当前用户权限
cache[requiredPermission] = userPermission === requiredPermission;
}
render() {
const hasPermission = cache[requiredPermission];
return hasPermission? <WrappedComponent {...this.props} /> : null;
}
};
};
};
function getCurrentUserPermission(): Permission {
// 实际实现中从本地存储、API等获取用户权限
return 'guest';
}
- 在组件中使用装饰器:
import React from'react';
interface MyComponentProps {
// 组件属性定义
}
const MyComponent: React.FC<MyComponentProps> = (props) => {
return <div>My Component Content</div>;
};
const AdminOnlyComponent = withPermission('admin')(MyComponent);
- 与React Router结合:
import { BrowserRouter as Router, Routes, Route } from'react-router-dom';
const App: React.FC = () => {
return (
<Router>
<Routes>
<Route path="/admin" element={<withPermission('admin')(AdminComponent) />} />
<Route path="/user" element={<withPermission('user')(UserComponent) />} />
</Routes>
</Router>
);
};
不同场景下的应用
- 组件级别权限控制:在单个组件定义时,使用
withPermission
装饰器,如上述AdminOnlyComponent
的定义,限制只有管理员能看到该组件。
- 路由级别权限控制:在React Router的路由配置中,对路由对应的组件使用
withPermission
装饰器,确保用户只能访问有权限的路由页面。例如,只有管理员能访问/admin
路径对应的页面。
- 动态权限更新:如果用户权限在运行时发生变化(如用户登录状态改变),可以通过重新渲染相关组件或触发权限检查逻辑更新缓存的方式,确保权限控制实时生效。例如,在用户登录/登出时,调用相关函数重新获取权限并更新缓存。