10分钟快速搭建React权限菜单设计
我又来了, react还剩下redux就结束了。就可以开展java、spring boot的学习流程了!!!
本次的功能实现基于上次的【工具篇】10分钟学会Ant Design of React用法,再次的基础上添加权限菜单设计,具体效果图如下:
1.创建角色
2.设置权限
3.用户授权
瓷们,走起学习了!!!
一、权限菜单设计基础概念
1.1 权限
“权”代表了“权利”,划分了系统的职权,不同的用户拥有不同的权利划分;“限”代表“限制”,在权利划分的基础上对职能范围进行了限制。
权限控制,赋予不同角色看到不同菜单的权限。权限能够较好的解决系统安全问题,不同部门使用系统互不感染,因此被系统广泛应用。
1.2 用户、角色
(1)用户
用户时指系统的登录用户,可以理解为一系列的人员。例如登录用户为张三、李四。
(2)角色
角色是用户在系统中担任的角色。例如总裁、经理、员工。
1.3 权限模型
(1)传统的权限模型
在早期中,传统的权限模型就是为用户分配菜单权限。缺点:随着人数增加,每一个员工都需要分配一次,效率太低。
(2)RBAC权限模型
RBAC,基于角色的访问控制(Role-Based Access Control),主要通过角色和权限建立管理,再赋予用户不同的角色,来实现权限控制的目标。
即先把权限赋予角色,即可完成权限的分配;再问用户分配相应的角色,即可直接获得角色拥有的权限。
愉快的代码学习开始了!!!
二、Antd Design of React实现权限菜单
2.1 创建角色
1.源码
<Button type="primary" onClick={
()=>this.onhandleAddRole("创建角色")}>创建角色</Button>
onhandleAddRole=(title)=>{
this.setState({
title:title,
visible:true
})
}
<Modal
title={
this.state.title}
visible={
this.state.visible}
footer={
null}
onCancel={
this.handleCancel}
>
<Form onFinish={
this.handleOk}>
<Form.Item label="角色名称" name="role_name" {
...formItemLayout} >
<Input placeholder="请输入角色名称"/>
</Form.Item>
<Form.Item label="状态" name="state" {
...formItemLayout} rules={
[{
required:true,message:"请选择角色状态!"}]}>
<Select placeholder="启用">
<Option value="1">启用</Option>
<Option value="2">弃用</Option>
</Select>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" style={
{
margin:'0 60px'}}>确认</Button>
<Button type="primary" onClick={
this.handleCancel}>取消</Button>
</Form.Item>
</Form>
</Modal>
2.效果
2.2 设置权限
1.源码
实现过程:先读取menuconfig生成tree树,再从后端读取数据的已选择好的页面。
<Button type="primary" onClick={
()=>this.onhandleAddPerm("设置权限")}>设置权限</Button>
// 设置权限
onhandleAddPerm=(title)=>{
let item = this.state.selectedRow;
if(!item){
message.error("请先选择一个角色")
return;
}
console.log(item)
let role_id = item.role_name;
let role_name = "";
if(role_id==1){
role_name="管理人员";
}else if(role_id==2){
role_name="财务人员";
}else if(role_id==3){
role_name="市场人员";
}
let state = item.status;
this.formRef.current.setFieldsValue({
role_name:role_name,
state:state
})
// let data = Object.assign({},this.state.roleInfo,{id:item.id,role_name:role_name,create_time:item.create_time,status:item.status,authorize_time:item.authorize_time,authorize_user_name:item.authorize_user_name});
this.setState({
title:title,
visiblePer:true,
menuInfo:item.menus
})
}
onCheck=(checkedKeys)=>{
// console.log(checkedKeys)
this.setState({
menuInfo:checkedKeys
})
}
<Modal
title={
this.state.title}
visible={
this.state.visiblePer}
footer={
null}
onCancel={
this.handleCancelPer}
forceRender={
true}
>
{
/*ref绑定到form*/}
<Form ref={
this.formRef} onFinish={
this.handleOkPer}>
<Form.Item label="角色名称" name="role_name" {
...formItemLayout} rules={
[{
required:true,message:"请输入用户名!"}]}>
<Input disabled placeholder="请输入角色名称"/>
</Form.Item>
<Form.Item label="状态" name="state" {
...formItemLayout} rules={
[{
required:true,message:"请选择角色状态!"}]}>
<Select placeholder="启用">
<Option value="1">启用</Option>
<Option value="2">弃用</Option>
</Select>
</Form.Item>
<Tree
checkable
defaultExpandAll
treeData={
menuConfig}
checkedKeys={
this.state.menuInfo}
onCheck={
(checkedKeys)=>{
this.onCheck(checkedKeys);
}}
>
{
/* <TreeNode title="平台权限" key="platform_all">
{this.renderTreeNodes(menuConfig)}
</TreeNode> */}
</Tree>
<Form.Item>
<Button type="primary" htmlType="submit" style={
{
margin:'0 60px'}}>确认</Button>
<Button type="primary" onClick={
this.handleCancelPer}>取消</Button>
</Form.Item>
</Form>
</Modal>
2.效果展示
2.3 用户授权
1.源码
<Button type="primary" onClick={
()=>this.onhandleAddUser("用户授权")}>用户授权</Button>
// 用户设置权限
onhandleAddUser=(title)=>{
let item = this.state.selectedRow;
if(!item){
message.error("请先选择一个角色")
return;
}
let role_id = item.role_name;
let role_name = "";
if(role_id==1){
role_name="管理人员";
}else if(role_id==2){
role_name="财务人员";
}else if(role_id==3){
role_name="市场人员";
}
this.formRef_User.current.setFieldsValue({
role_name:role_name,
})
this.setState({
title:title,
visibleUser:true
})
// 筛选出符合要求的
this.getUserRole();
}
componentDidMount(){
// 获取所有数据
this.getUserRoleList();
}
// 获取用户框
getUserRoleList=()=>{
axios.ajax({
url:"/role/add_user"
}).then((res)=>{
if(res.code=='0'){
this.setState({
userListData:res.result.item_list
})
}
})
}
// 筛选出符合要求的用户
getUserRole=()=>{
const dataSource = this.state.userListData;
const targetKeys = [];
const mockData = [];
for(let i=0;i<dataSource.length;i++){
const data = {
key:dataSource[i].user_id,
title:dataSource[i].user_name,
status:dataSource[i].status
}
if(data.status==1){
targetKeys.push(data.key);
}
mockData.push(data);
}
this.setState({
mockData,targetKeys
});
console.log(mockData)
console.log(targetKeys)
}
<Modal
title={
this.state.title}
visible={
this.state.visibleUser}
footer={
null}
onCancel={
this.handleCancelUser}
forceRender={
true}
>
{
/*ref绑定到form*/}
<Form ref={
this.formRef_User} onFinish={
this.handleOkUser}>
<Form.Item label="角色名称" name="role_name" {
...formItemLayout} >
<Input disabled/>
</Form.Item>
<Form.Item label="选择用户"{
...formItemLayout} >
<Transfer
listStyle={
{
width:200,height:400}}
title={
["待选用户","已选用户"]}
dataSource={
this.state.mockData}
targetKeys={
this.state.targetKeys}
showSearch
searchPlaceholder="输入用户名"
filterOption={
this.filterOption}
onChange={
this.handleChange}
render={
item => item.title}
/>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" style={
{
margin:'0 60px'}}>确认</Button>
<Button type="primary" onClick={
this.handleCancelUser}>取消</Button>
</Form.Item>
</Form>
</Modal>
2.效果展示
最后的话,就是之前form表单遗留了几个问题,现在解决了,记录一下。
三、问题
3.1 问题1 form表单赋值
之前做的form表单赋值问题,已解决。antd4.0版本与之前的赋值不同,而且官网只是浅浅的介绍了几句~~
三步走来解决这个问题
// 创建一个ref
formRef = React.createRef();
{
/*ref绑定到form*/}
<Form ref={
this.formRef} onFinish={
this.handleOkPer}>
<Form.Item label="角色名称" name="role_name" {
...formItemLayout} rules={
[{
required:true,message:"请输入用户名!"}]}>
<Input disabled placeholder="请输入角色名称"/>
</Form.Item>
<Form.Item label="状态" name="state" {
...formItemLayout} rules={
[{
required:true,message:"请选择角色状态!"}]}>
<Select placeholder="启用">
<Option value="1">启用</Option>
<Option value="2">弃用</Option>
</Select>
</Form.Item>
<Tree
checkable
defaultExpandAll
treeData={
menuConfig}
checkedKeys={
this.state.menuInfo}
onCheck={
(checkedKeys)=>{
this.onCheck(checkedKeys);
}}
>
{
/* <TreeNode title="平台权限" key="platform_all">
{this.renderTreeNodes(menuConfig)}
</TreeNode> */}
</Tree>
<Form.Item>
<Button type="primary" htmlType="submit" style={
{
margin:'0 60px'}}>确认</Button>
<Button type="primary" onClick={
this.handleCancelPer}>取消</Button>
</Form.Item>
</Form>
// 赋初值
this.formRef_User.current.setFieldsValue({
role_name:role_name,
})
3.2 问题2 form表单抽离
class OpenCityForm extends React.Component{
styduonFinish=(values)=>{
this.props.onFinish(values);
}
stydyonCancel=()=>{
this.props.onCancel();
}
render(){
const formItemLayout = {
labelCol:{
span:5
},
wrapperCol:{
span:10
}
}
return(
<Form layout="horizontal" onFinish={
this.styduonFinish} >
<Form.Item label="选择城市" {
...formItemLayout} name="city">
<Select>
<Option value="">全部</Option>
<Option value="1">北京市</Option>
<Option value="2">天津市</Option>
</Select>
</Form.Item>
<Form.Item label="营运模式" {
...formItemLayout} name="use_mode">
<Select>
<Option value="1">自营</Option>
<Option value="2">加盟</Option>
</Select>
</Form.Item>
<Form.Item label="用车模式" {
...formItemLayout} name="car_mode">
<Select>
<Option value="1">指定停车点</Option>
<Option value="2">禁停区</Option>
</Select>
</Form.Item>
<Form.Item {
...formItemLayout}>
<Row>
<Col span={
12}>
<Button type="primary" htmlType="submit" >
确认
</Button>
</Col>
<Col span={
12}>
<Button onClick={
this.stydyonCancel}>
取消
</Button>
</Col>
</Row>
</Form.Item>
</Form>
)
}
}
<OpenCityForm ref="child" onRef={
this.onRef} onFinish={
this.onFinish} onCancel={
this.onCancel}/>
// 提交开通城市
onFinish=(values)=>{
console.log(values);
axios.ajax({
url:"/city/open",
data:{
param:values
}
}).then((res)=>{
if(res.code=='0'){
message.success("开通成功!");
this.setState({
isShowOpenCity:false
})
this.requestList();
}
})
}
// 取消开通城市
onCancel=()=>{
this.setState({
isShowOpenCity:false
})
}
最后,接着leetcode的学习,react的redux的学习。结束redux,就马不停蹄开java的spring boot框架!!!
转载:https://blog.csdn.net/Mind_programmonkey/article/details/109059292