当前位置: 首页 > news >正文

React新闻发布系统 角色列表篇

好久没写了 项目写到一半才想起来写这个(汗)

一 基础页面搭建

角色列表页面的结构与之前编写的权限列表基本一致,仅在部分功能上有所差异。我们可以参考权限列表的实现方式快速搭建角色列表页面。

其中:

  • dataSource 用于渲染角色数据
  • rightList 存储权限数据
  • 这两个数据都通过axios请求获取
import React from 'react'
import {Table ,Tree,Modal} from 'antd';
import { useState,useEffect} from 'react';
import axios from 'axios';
import {Button,Popconfirm,Popover} from 'antd';
import{ DeleteOutlined,UnorderedListOutlined
}from '@ant-design/icons'
export default function RoleList() {const [dataSource,setDataSource]=useState([]);const [rightList,setRightList]=useState([]);useEffect(()=>{const getDataSource=async()=>{const res=await axios.get('http://localhost:3000/roles')const right=await axios.get('http://localhost:3000/rights?_embed=children')setDataSource(res.data);setRightList(right.data)}getDataSource();},[])const columns=[{title:'ID',dataIndex:'id',key:'id'},{title:'角色名称',dataIndex:'roleName',key:'roleName'},{title:'操作',render:(item)=>{return<><Popconfirm title="确定删除吗?" okText="确定" cancelText="取消" onConfirm={()=>{confirmDelete(item)}}><Button icon={<DeleteOutlined/>} shape='circle' danger></Button></Popconfirm><Button icon={<UnorderedListOutlined />} shape='circle' color='blue' onClick={()=>showModal(item)}></Button></>}}]return (<div>{/*rowKey 如果数据中没有key这个属性,那就使用这个方法来赋值 表格行 key 的取值,可以是字符串或一个函数 */}<Table dataSource={dataSource} columns={columns} pagination={{pageSize:5}} rowKey={(item)=>item.id}/></div>) 
}

然后就能得到一个和权限列表相似的界面了(不好看 但也不是很丑哈哈)

二 操作栏样式编写与函数方法实现

(1) antd组件认识

我们现在来关注一下操作栏 先来看看点击编辑的时候弹出的效果

点击编辑按钮会弹出树形权限结构图,通过勾选相应节点即可为角色分配权限。该功能实现主要依赖antd的Tree组件(树形控件)。编辑

除此之外还行要一个模态框 用来包裹住他

(2)代码编写

然后在代码中我们分别写好模态框与树形控件:

1.所需状态与函数方法定义

创建用于控制状态的定义和相关函数:

  • confirmDelete:处理删除按钮点击后的确认操作,在弹窗中执行删除逻辑
  • showModal:控制树形控件模态框的显示/隐藏状态
  • handleOk:在树形控件中修改数据后点击确定按钮时触发,负责前后端数据交互
  • onCheck:处理树形控件节点勾选事件,checkKeys返回被选权限组成的数组并保存该权限数据
  const [isModalOpen, setIsModalOpen] = useState(false);const [currentRight,setCurrentRight]=useState({})const [currentID,setCurrentID]=useState(0)const confirmDelete=(item)=>{}const showModal = (item) => {};const handleOK=(currentID)=>{}const onCheck=(checkedKeys)=>{}

2.html部分写法

    <div>{/*rowKey 如果数据中没有key这个属性,那就使用这个方法来赋值 表格行 key 的取值,可以是字符串或一个函数 */}<Table dataSource={dataSource} columns={columns} pagination={{pageSize:5}} rowKey={(item)=>item.id}/><ModalonOk={()=>handleOK(currentID)}onCancel={() => setIsModalOpen(false)}title="权限分配"open={isModalOpen}><Treecheckable// defaultCheckeys是一个非受控的组件 意思是这个组件只会显示默认选中的节点,不会受后续的修改 后续修改后也会不刷新组件//在antd中一般加上default属性都是非受控的checkedKeys={currentRight} //受控组件 但是表单里面的节点只能通过状态来控制onCheck={onCheck} //可以修改状态 来改变受控组件的结果treeData={rightList}// 可能是版本问题 如果不添加自定义属性 所有的数据都会被占位符代替 可能是因为我的数据和tree遍历的方法有冲突checkStrictly={true}// 不进行父子关联(父项勾选 子项全都被勾选) fieldNames={{title: 'label',key: 'key'}}/></Modal></div>

3.前后端交互函数的编写

item的解释

很多函数中都有item,这个item其实是渲染函数render的参数 我们点击那一项 item就是这一项的对象

render:(item)=>{return<><Popconfirm title="确定删除吗?" okText="确定" cancelText="取消" onConfirm={()=>{confirmDelete(item)}}><Button icon={<DeleteOutlined/>} shape='circle' danger></Button></Popconfirm><Button icon={<UnorderedListOutlined />} shape='circle' color='blue' onClick={()=>showModal(item)}></Button></>}
1.confirDelete函数

这个函数的作用是用来删除当前角色的 逻辑很简单 通过filter方法将当前所选的角色筛出渲染数据 ,然后通过axios向后端发送delete请求就可以

  const confirmDelete=(item)=>{//前端删除逻辑setDataSource(dataSource.filter(data=>data.id!==item.id))//后端删除逻辑axios.delete(`http://localhost:3000/roles/${item.id}`).then((err)=>{if(err){console.log(err);}})}
2.showModal函数

作用是用来控制当前的模态框显示的 并在显示的时候将当前没有操作的数据保存起来 并且记录当前操作的角色id

  const showModal = (item) => {setIsModalOpen(true);//将当前未操作的权限保存起来setCurrentRight(item.rights)//记录当前操作的角色idsetCurrentID(item.id)};
3.onCheck函数

是树形控件的自带的函数 用来记录当前操作完成后返回的权限数组

 const onCheck=(checkedKeys)=>{//每次点击完一个节点之后 会返回一个新的节点数组console.log(checkedKeys);//将当前操作完的权限保存起来setCurrentRight(checkedKeys.checked)}
4.handleOk函数

该函数用于处理树形控件操作后的提交确认流程:首先关闭模态框,随后遍历项目列表,查找与先前保存的操作角色ID匹配的条目。找到对应角色后,通过展开运算符将其权限更新为操作后返回的权限数组(currentRight)。

  const handleOK=(currentID)=>{setIsModalOpen(false)//同步datasourcesetDataSource(dataSource.map(item=>item.id===currentID?{...item,rights:currentRight}:item))//同步后端axios.patch(`http://localhost:3000/roles/${currentID}`,{rights:currentRight})}

三 完整代码展示:

import React from 'react'
import {Table ,Tree,Modal} from 'antd';
import { useState,useEffect} from 'react';
import axios from 'axios';
import {Button,Popconfirm,Popover} from 'antd';
import{ DeleteOutlined,UnorderedListOutlined
}from '@ant-design/icons'
export default function RoleList() {const [dataSource,setDataSource]=useState([]);const [rightList,setRightList]=useState([]);const [isModalOpen, setIsModalOpen] = useState(false);const [currentRight,setCurrentRight]=useState({})const [currentID,setCurrentID]=useState(0)useEffect(()=>{const getDataSource=async()=>{const res=await axios.get('http://localhost:3000/roles')const right=await axios.get('http://localhost:3000/rights?_embed=children')setDataSource(res.data);setRightList(right.data)}getDataSource();},[])const columns=[{title:'ID',dataIndex:'id',key:'id'},{title:'角色名称',dataIndex:'roleName',key:'roleName'},{title:'操作',render:(item)=>{return<><Popconfirm title="确定删除吗?" okText="确定" cancelText="取消" onConfirm={()=>{confirmDelete(item)}}><Button icon={<DeleteOutlined/>} shape='circle' danger></Button></Popconfirm><Button icon={<UnorderedListOutlined />} shape='circle' color='blue' onClick={()=>showModal(item)}></Button></>}}]const confirmDelete=(item)=>{//前端删除逻辑setDataSource(dataSource.filter(data=>data.id!==item.id))//后端删除逻辑axios.delete(`http://localhost:3000/roles/${item.id}`).then((err)=>{if(err){console.log(err);}})}const showModal = (item) => {setIsModalOpen(true);//将当前未操作的权限保存起来setCurrentRight(item.rights)//记录当前操作的角色idsetCurrentID(item.id)};const handleOK=(currentID)=>{setIsModalOpen(false)//同步datasourcesetDataSource(dataSource.map(item=>item.id===currentID?{...item,rights:currentRight}:item))//同步后端axios.patch(`http://localhost:3000/roles/${currentID}`,{rights:currentRight})}const onCheck=(checkedKeys)=>{//每次点击完一个节点之后 会返回一个新的节点数组console.log(checkedKeys);//将当前操作完的权限保存起来setCurrentRight(checkedKeys.checked)}return (<div>{/*rowKey 如果数据中没有key这个属性,那就使用这个方法来赋值 表格行 key 的取值,可以是字符串或一个函数 */}<Table dataSource={dataSource} columns={columns} pagination={{pageSize:5}} rowKey={(item)=>item.id}/><ModalonOk={()=>handleOK(currentID)}onCancel={() => setIsModalOpen(false)}title="权限分配"open={isModalOpen}><Treecheckable// defaultCheckeys是一个非受控的组件 意思是这个组件只会显示默认选中的节点,不会受后续的修改 后续修改后也会不刷新组件//在antd中一般加上default属性都是非受控的checkedKeys={currentRight} //受控组件 但是表单里面的节点只能通过状态来控制onCheck={onCheck} //可以修改状态 来改变受控组件的结果treeData={rightList}// 可能是版本问题 如果不添加自定义属性 所有的数据都会被占位符代替 可能是因为我的数据和tree遍历的方法有冲突checkStrictly={true}// 不进行父子关联(父项勾选 子项全都被勾选) fieldNames={{title: 'label',key: 'key'}}/></Modal></div>) 
}

http://www.dtcms.com/a/434310.html

相关文章:

  • 网站常用插件wordpress自定义应用
  • 衡水手机网站建设淮安市盱眙县建设局网站
  • iPhone美区账号登录指南:轻松下载ChatGPT应用
  • AI大模型:(三)1.6 Dify工作流快速搭建数据可视化助手
  • 软件/网站安全需要以及解决方法
  • 做设备推广的网站学做网站用谁的书
  • python 做网站速度网站建设及托管合同
  • Coze源码分析-资源库-编辑工作流-后端源码-数据存储/安全/错误
  • 什么是Java反射机制?
  • 使用Docker安装Neo4j
  • 建立网站的步骤筝晃湖南岚鸿官网深圳专业建设网站哪个公司好
  • 20软件测试需求分析评审
  • SQL 多表查询实用技巧:ON 和 WHERE 的区别速览
  • 网站备案 内容央企八大设计院
  • 从汇编角度看C++优化:编译器真正做了什么
  • 分布式专题——25 深入理解网络通信和TCP、IP协议
  • UV python多版本管理
  • Schema是什么?
  • 许昌做网站优化wordpress 控制每页显示文章数
  • MAX31865模块和PT100实现温度测量使用配置笔记教程
  • Elasticsearch MCP 服务器:与你的 Index 聊天
  • 【ROS2学习笔记】话题通信篇:话题通信再探
  • 网络编程中“地址重用(SO_REUSEADDR)”
  • 汕头网站建设推广厂家wordpress 响应式图片
  • Rust的错误处理
  • 可视化地图
  • Rust与C接口交互
  • 【C++实战(64)】C++ 邂逅SQLite3:数据库编程实战之旅
  • 泉州网页建站模板开发网址
  • 中华建设杂志网站记者管理网站英文