权限管理不在只是后端的事情了,现在权限分为了前端权限与后端权限。
前端权限,主要是两部分:一是控制显示,没有对应权限不进行显示,二是拦截非法的请求,下文介绍了在React中去做前端权限的步骤与代码:
React中的权限管理
1. antd ui框架来做
框架下载
安装axios ,react-router-dom,mobx,mobx-react ,
babel(装饰器)相关的,antd
引用antd
代码语言:javascript复制import { Button } from 'antd';
修改 src/App.css,
添加@import '~antd/dist/antd.css';
2. 项目架构
public
src
|-- component 组件
|-- pages 页面级组件
|-- assets 资源文件
|-- router 路由相关文件
|-- store 状态
|-- api 请求接口
|-- util 公共的Js文件,比如,发邮件,发短信
app.css
app.js
index.js
3. 权限管理实现
3.1 登录 => 点击登录,进行登录判断,如果登录成功,获取登录数据数据有:
token
userInfo : 用户相关数据
menuInfo: 用户有权访问的模块
以上,都是后台数据返回,在获取数据后,存储在mobx中,代码如下
代码语言:javascript复制@observable user =[]
@observable token = ""
@action
login=(user,pwd)=>{
return new Promise((resolve,reject)=>{
Axios.post(Api.user.userLogin,
{userName:user,userPwd:pwd}
)
.then((res)=>{
console.log(res)
if(res.data.returnCode===200){
console.log(res.data.data)
this.user = res.data.data;
this.token = res.data.token;
resolve('登录成功')
}else{
reject('登录失败')
}
})
})
}
用户点击登录按钮,触发mobx的登录操作
代码语言:javascript复制//需要将值 ,提到服务器端进行判断
this.props.user.login(obj.username,obj.password)
then((data)=>{
this.props.history.push("/index")
}).catch(function(err){
console.log(err)
});
3.2 首页 =》显示后台管理的框架,左边菜单(动态加载) ,上面,也可以菜单,右边,显示不同页面即:点击左边的菜单,右边发生变化,需要添加链接,还需要动态添加路由(Router)
3.2.1左边动态菜单
代码如下:
代码语言:javascript复制bindMenu(menulist){
let MenuList= menulist.map((item,index)=>{
if(item.menuChilds.length===0){ //没有子菜单
let IconMenu =antIcons[item.menuImgClass];
return <Menu.Item key={item.menuId} icon={ <IconMenu />}>
<Link to={item.menuUrl}>{item.menuName}</Link>
</Menu.Item>
}
else{
let IconMenu =antIcons[item.menuImgClass];
return <SubMenu key={item.menuId} icon={ <IconMenu />} title={item.menuName}>
{this.bindMenu(item.menuChilds)}
</SubMenu>
}
})
return MenuList;
}
componentDidMount(){
let menuList =this.bindMenu(this.props.user.user.menuInfo);
this.setState({
leftMenu :menuList
})
}
3.2.2 动态路由
代码如下:
代码语言:javascript复制bindRouter(list){
let routerList= list.map((item)=>{
if(item.menuChilds.length===0){
return <Route key={item.menuId} path={item.menuUrl} component={ loadable(() => import(`./${item.componentPath}`))}/>
}else{
// return [...this.bindRouter(item.menuChilds),<Route key={item.menuId} path={item.menuUrl} component={ loadable(() => import(`./${item.componentPath}`))}/>]
return <Route key={item.menuId} path={item.menuUrl} render={() =>{
let ComponentName =loadable(() => import(`./${item.componentPath}`));
return <ComponentName {...this.props}>
{this.bindRouter(item.menuChilds)}
</ComponentName>
}}>
</Route>
}
})
return routerList;
}
componentDidMount(){
let menuList =this.bindRouter(this.props.user.user.menuInfo);
this.setState({
routerList :menuList
})
}
3.2.3 首页
引用菜单组件,与路由组件
代码语言:javascript复制render()
{
return (
<Layout>
<Header className="header">
<div className="logo" />
<Menu theme="dark" mode="horizontal" defaultSelectedKeys={['2']}>
<Menu.Item key="1">nav 1</Menu.Item>
<Menu.Item key="2">nav 2</Menu.Item>
<Menu.Item key="3">nav 3</Menu.Item>
</Menu>
</Header>
<Layout>
<Sider width={200} className="site-layout-background">
{/*这里写一个组件,根据数据生成Menu*/}
<LeftMenu />
</Sider>
<Layout style={{ padding: '0 24px 24px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<Content
className="site-layout-background"
style={{
padding: 24,
margin: 0,
minHeight: 280,
}}
>
<PrivateRouter/>
</Content>
</Layout>
</Layout>
</Layout>
)
}
源码地址:https://github.com/doubleyong/reactRole.git
需要源码的,可以到github下载,欢迎一起讨论