项目实战--权限列表
后端数据:

用表格实现权限列表
const dataSource = [{key: '1',name: '胡彦斌',age: 32,address: '西湖区湖底公园1号',},{key: '2',name: '胡彦祖',age: 42,address: '西湖区湖底公园1号',},
];const columns = [{title: '姓名',dataIndex: 'name',key: 'name',},{title: '年龄',dataIndex: 'age',key: 'age',},{title: '住址',dataIndex: 'address',key: 'address',},
];<Table dataSource={dataSource} columns={columns} />;

可以通过dataIndex这个值决定将来要将哪一项显示在table列中

设置好看的圆角按钮:
<Button type="primary" shape="circle" icon={<SearchOutlined />} />
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag } from 'antd';
import { EditOutlined,DeleteOutlined } from '@ant-design/icons';
import axios from 'axios';function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights").then(res=>{setdataSource(res.data)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '权限名称',dataIndex: 'title',},{title: '权限路径',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(key)=>{return <div><Button type="primary" shape="circle" icon={<EditOutlined />} /><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} /></div>}},];return (<div><Table dataSource={dataSource} columns={columns} /></div>);
}export default RightList;
这个实现的看分页器或者滚动条

如果不用滚动条的话还可以使用分页器

Table表格数据实现树形结构
表格是支持树形数据的展示的,当数据中有children字段的时候会自动的展示为树形表格,如果不需要或者配置为其他字段则可以用childrenColumnName进行配置
可以通过设置indentSize以控制每一层的缩进宽度
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag } from 'antd';
import { EditOutlined,DeleteOutlined } from '@ant-design/icons';
import axios from 'axios';function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights?_embed=children").then(res=>{const list = res.datalist[0].children = ""setdataSource(res.data)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '权限名称',dataIndex: 'title',},{title: '权限路径',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(key)=>{return <div><Button type="primary" shape="circle" icon={<EditOutlined />} /><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} /></div>}},];return (<div><Table dataSource={dataSource} columns={columns} pagination={{//一页显示几条数据pageSize:5}}/></div>);
}export default RightList;

把children字段改一下首页就不会展开了
添加气泡框

使用对话框和气泡框都可以实现想要的效果
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag,Modal } from 'antd';
import { EditOutlined,DeleteOutlined,ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
const { confirm } = Modal;function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights?_embed=children").then(res=>{const list = res.datalist[0].children = ""setdataSource(res.data)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '权限名称',dataIndex: 'title',},{title: '权限路径',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(record)=>{return <div><Button type="primary" shape="circle" icon={<EditOutlined />}/><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} onClick={()=>confirmMethod(record)}/></div>}},];const confirmMethod = (record) => {confirm({title: 'Do you Want to delete these items?',icon: <ExclamationCircleOutlined />,onOk() {console.log('OK',record);},onCancel() {console.log('Cancel');},});console.log('确认删除')};return (<div><Table dataSource={dataSource} columns={columns} pagination={{//一页显示几条数据pageSize:5}}/></div>);
}export default RightList;
删除还要同步一下后端的数据,以及之前的一种写死的写法要做出改进,否则删除完一个之后其他的不支持展开了:
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag,Modal } from 'antd';
import { EditOutlined,DeleteOutlined,ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
const { confirm } = Modal;function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights?_embed=children").then(res=>{const list = res.data// list[0].children = "" 不建议写死list.forEach(item=>{if(item.children.length===0){item.children = ""}})setdataSource(list)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '权限名称',dataIndex: 'title',},{title: '权限路径',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(record)=>{return <div><Button type="primary" shape="circle" icon={<EditOutlined />}/><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} onClick={()=>confirmMethod(record)}/></div>}},];const confirmMethod = (record) => {confirm({title: 'Do you Want to delete these items?',icon: <ExclamationCircleOutlined />,onOk() {deleteMethod(record)},onCancel() {console.log('Cancel');},});console.log('确认删除')};const deleteMethod = (record) => {console.log(record)//同步状态 页面setdataSource(dataSource.filter(item=>item.id!==record.id))//同步状态 后端axios.delete(`http://localhost:3000/rights/${record.id}`)}return (<div><Table dataSource={dataSource} columns={columns} pagination={{//一页显示几条数据pageSize:5}}/></div>);
}export default RightList;
但是现在的代码删除children会出现问题
删除孩子就是根据id这个属性向后端发请求
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag,Modal } from 'antd';
import { EditOutlined,DeleteOutlined,ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
import { data } from 'react-router-dom';
const { confirm } = Modal;function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights?_embed=children").then(res=>{const list = res.data// list[0].children = "" 不建议写死list.forEach(item=>{if(item.children.length===0){item.children = ""}})setdataSource(list)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '权限名称',dataIndex: 'title',},{title: '权限路径',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(record)=>{return <div><Button type="primary" shape="circle" icon={<EditOutlined />}/><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} onClick={()=>confirmMethod(record)}/></div>}},];const confirmMethod = (record) => {confirm({title: 'Do you Want to delete these items?',icon: <ExclamationCircleOutlined />,onOk() {deleteMethod(record)},onCancel() {console.log('Cancel');},});console.log('确认删除')};const deleteMethod = (record) => {console.log(record);if (record.grade === 1) {// 删除一级权限//同步状态 页面setdataSource(dataSource.filter(item => item.id !== record.id));//同步状态 后端axios.delete(`http://localhost:3000/rights/${record.id}`);} else {// 找到对应的父级权限//用maplet list = dataSource.map(item => {if (item.id === record.rightId) {//修正children为数组return {...item,children: Array.isArray(item.children) ? item.children.filter(child => child.id !== record.id) : []};}return item;});//同步状态setdataSource(list);axios.delete(`http://localhost:3000/children/${record.id}`);}};return (<div><Table dataSource={dataSource} columns={columns} pagination={{//一页显示几条数据pageSize:5}}/></div>);
}export default RightList;
需要注意的是要修改children为数组,避免filter方法出错
点击气泡框:

有些没有权限的就禁用:
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag,Modal,Popover, Switch } from 'antd';
import { EditOutlined,DeleteOutlined,ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
import { data } from 'react-router-dom';
const { confirm } = Modal;function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights?_embed=children").then(res=>{const list = res.data// list[0].children = "" 不建议写死list.forEach(item=>{if(item.children.length===0){item.children = ""}})setdataSource(list)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '权限名称',dataIndex: 'title',},{title: '权限路径',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(record)=>{return <div><Popover content={<div style={{textAlign:"center"}}><Switch checked= {record.pagepermisson} onChange={()=>SwitchMethod(record)}></Switch>{/* pagepermission是否存在,不存在的话就禁用 */}</div>} title="配置项" trigger={record.pagepermisson === undefined?'':'click'}><Button type="primary" shape="circle" icon={<EditOutlined />} disabled={record.pagepermisson === undefined }/>{/* 如果没有配置权限,就不显示 */}</Popover><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} onClick={()=>confirmMethod(record)}/></div>}},];const SwitchMethod = (record) => {record.pagepermisson = record.pagepermisson===1?0:1//同步状态 页面setdataSource([...dataSource])if(record.grade===1){// 同步状态 后端 axios.patch(`http://localhost:3000/rights/${record.id}`,{pagepermisson:record.pagepermisson})}else{axios.patch(`http://localhost:3000/children/${record.id}`,{pagepermisson:record.pagepermisson})}}const confirmMethod = (record) => {confirm({title: 'Do you Want to delete these items?',icon: <ExclamationCircleOutlined />,onOk() {deleteMethod(record)},onCancel() {console.log('Cancel');},});console.log('确认删除')};const deleteMethod = (record) => {console.log(record);if (record.grade === 1) {// 删除一级权限//同步状态 页面setdataSource(dataSource.filter(item => item.id !== record.id));//同步状态 后端axios.delete(`http://localhost:3000/rights/${record.id}`);} else {// 找到对应的父级权限//用maplet list = dataSource.map(item => {if (item.id === record.rightId) {//修正children为数组return {...item,children: Array.isArray(item.children) ? item.children.filter(child => child.id !== record.id) : []};}return item;});//同步状态setdataSource(list);axios.delete(`http://localhost:3000/children/${record.id}`);}};return (<div><Table dataSource={dataSource} columns={columns} pagination={{//一页显示几条数据pageSize:5}}/></div>);
}export default RightList;
弹出气泡框的展示,配置成为可选项,同步后端数据, 更改状态,页面刷新

重视配置
上面的那个对话框因为antd只支持react 15 ~ 18,但是我的拉下来的项目的依赖是react19,所以需要改一下
以及如果json-server的版本不对也会出现莫名其妙的bug(数据拉取不过来)
划重点

相关文章:
项目实战--权限列表
后端数据: 用表格实现权限列表 const dataSource [{key: 1,name: 胡彦斌,age: 32,address: 西湖区湖底公园1号,},{key: 2,name: 胡彦祖,age: 42,address: 西湖区湖底公园1号,}, ];const columns [{title: 姓名,dataIndex: name,key: name,},{title: 年龄,dataInd…...
若依赖前端处理后端返回的错误状态码
【背景】 后端新增加了一个过滤器,用来处理前端请求中的session 若依赖存放过滤器的目录:RuoYi-Vue\ruoyi-framework\src\main\java\com\ruoyi\framework\security\filter\ 【问题】 后端返回了一个状态码为403的错误,现在前端需要处理这…...
【计网】数据包
期末复习自用的,处理得比较草率,复习的同学或者想看基础的同学可以看看,大佬的话可以不用浪费时间在我的水文上了 1.数据包的定义: 数据包是网络通信中的基本单元,它包含了通过网络传输的所有必要信息。数据包的结构…...
web权限划分提权和移权
前言:权限的基本认知 渗透权限划分:假如我们通过弱口令进入到web的后台 这样我们就拿到了web的管理员权限 管理员权限是web中最高的权限(一般我们进入web的时候数据库会进行用户权限的划分:假设 0-10为最高的权限 11-10000为普通…...
LocalDateTime序列化总结
版权说明: 本文由CSDN博主keep丶原创,转载请保留此块内容在文首。 原文地址: https://blog.csdn.net/qq_38688267/article/details/146703276 文章目录 1.背景2.序列化介绍常见场景关键问题 3.总体方案4.各场景实现方式WEB接口EasyExcelMybat…...
[ 春秋云境 ] Initial 仿真场景
文章目录 靶标介绍:外网内网信呼oa永恒之蓝hash传递 靶标介绍: Initial是一套难度为简单的靶场环境,完成该挑战可以帮助玩家初步认识内网渗透的简单流程。该靶场只有一个flag,各部分位于不同的机器上。 外网 打开给的网址, 有一…...
unity 截图并且展现在UI中
using UnityEngine; using UnityEngine.UI; using System.IO; using System.Collections.Generic; using System; using System.Collections;public class ScreenshotManager : MonoBehaviour {[Header("UI 设置")]public RawImage latestScreenshotDisplay; // 显示…...
XHR.readyState详解
XHR.readyState详解 引言 XHR.readyState是XMLHttpRequest对象的一个属性,它反映了当前请求的状态。在Ajax编程中,正确理解和使用XHR.readyState对于调试和确保异步请求的正确执行至关重要。本文将详细介绍XHR.readyState的属性值、含义以及在Ajax请求中的具体应用。 XHR.…...
SQL Server数据库引擎服务启动失败:端口冲突
问题现象: SQL Server 2022 安装完成后,数据库引擎服务无法启动,日志报错 “TCP 端口 1433 已被占用”(ERROR_LOG_SYS_TCP_PORT)。 快速诊断 检测端口占用: # 查看 1433 端口占用情况(需管理员权…...
前端知识点---用正则表达式判断邮箱(javascript)
// 全面的正则(兼容大多数情况) const emailRegex /^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$/;// 或直接使用浏览器内置验证 <input type"email" required>/:正则表达式的起始和结束标志。 ^:匹配字符串的…...
中断管理常用API(四)
一、request_irq(...) request_irq 函数主要用于硬中断相关操作,它的核心作用是把一个中断处理函数和特定的中断号进行绑定。当硬件设备触发该中断号对应的中断时,内核就会调用绑定的中断处理函数,像 irqhandler_func 这类。 此函数在多种硬件…...
RabbitMQ高级特性--重试特性
目录 1.重试配置 2.配置交换机&队列 3.发送消息 4.消费消息 5. 运行程序观察结果 6. 手动确认 注意: 在消息传递过程中, 可能会遇到各种问题, 如网络故障, 服务不可用, 资源不足等, 这些问题可能导致消息处理失败. 为了解决这些问题, RabbitMQ 提供了重试机制, …...
pyspark学习rdd处理数据方法——学习记录
python黑马程序员 """ 文件,按JSON字符串存储 1. 城市按销售额排名 2. 全部城市有哪些商品类别在售卖 3. 上海市有哪些商品类别在售卖 """ from pyspark import SparkConf, SparkContext import os import jsonos.environ[PYSPARK_P…...
C语言入门教程100讲(0)从了解C语言的发展史开始
文章目录 引言1. C语言的起源2. C语言的诞生3. C语言的标准化4. C语言的进一步发展5. C语言的影响与应用6. C语言的未来结语引言 C语言作为一种高效、灵活且具有广泛应用的编程语言,在计算机科学史上占据着举足轻重的地位。它的设计不仅影响了后来的编程语言,也对操作系统、…...
【HTML 基础教程】HTML <head>
HTML <head> 查看在线实例 - 定义了HTML文档的标题"><title> - 定义了HTML文档的标题 使用 <title> 标签定义HTML文档的标题 - 定义了所有链接的URL"><base> - 定义了所有链接的URL 使用 <base> 定义页面中所有链接默认的链接目…...
练习题:111
目录 Python题目 题目 题目分析 需求理解 关键知识点 实现思路分析 代码实现 代码解释 指定文件路径和名称: 定义要写入的内容: 打开文件并写入内容: 异常处理: 输出提示信息: 运行思路 结束语 Python题…...
混合知识表示系统框架python示例
前文我们已经深入学习了框架表示法、产生式规则和一阶谓词逻辑,并对它们进行了深度对比,发现它们在不同的应用场景下各有优缺点。 一阶谓词逻辑适合复杂逻辑推理场景,具有数学定理证明、形式化系统规范的优点;产生式规则适合动态决策系统,支持实时决策(如风控、诊断),规…...
信号集操作函数
目录 一、sigpending函数 功能: 头文件: 函数原型: 函数参数: 返回值: 二、sigemptyset函数 功能: 原型: 参数: 返回值: 三、sigfillset函数 功能…...
学习不同电脑cpu分类及选购指南
关于电脑cpu 一、CPU型号的核心组成与命名规则Intel命名规则:AMD命名规则:5. 后缀:Intel常见后缀及其含义:AMD后缀一些常见的后缀及其含义:二、主流品牌CPU的分类与性能差异三、区分CPU型号的实用方法四、主流品牌CPU对比与选择建议五、选购CPU的注意事项关于不同主流CPU的…...
MATLAB 控制系统设计与仿真 - 30
用极点配置设计伺服系统 方法2-反馈修正 如果我们想只用前馈校正输入,从而达到伺服控制的效果,我们需要很精确的知道系统的参数模型,否则系统输出仍然具有较大的静态误差。 但是如果我们在误差比较器和系统的前馈通道之间插入一个积分器&a…...
Baklib知识中台驱动智能架构升级
构建四库体系驱动架构升级 在数字化转型过程中,企业普遍面临知识资源分散、隐性经验难以沉淀的痛点。Baklib通过构建知识库、案例库、流程库及资源库四层核心体系,为知识中台搭建起结构化基础框架。知识库以AI分类引擎实现文档标签化存储,案…...
IP第一次笔记
一、TCP协议 第0步:如果浏览器和host文件存在域名对应的P地址记录关系 则直接封装HTTP数据报文,如果没有记录则触发DNS解析获 取目标域名对应的P地址 第一步:终端主机想服务器发起TCP三次握手 1.TCP的三次握手 2.传输网页数据 HTTP --应用层…...
计算机三级信息安全部分英文缩写
eip,指令寄存器,用于存放指向下一条将执行指令的指针,即返回地址栈顶指针esp基址指针寄存器EBP,基地址数据执行保护DEP(Data Execute Prevention)技术可以设置内存堆栈区的代码为不可执行状态,从而防范溢出后代码的执行…...
Supplements of My Research Proposal: My Perspectives on the RAG
To build an agent, I think there’re a lot of things that can be considered from humans. For example, how do self-learners learn things? I think 2 sources of knowledge can never be ignored: textbooks and online cources. A question then arise: how do we …...
【安全】nginx防止host头攻击
host攻击 系统上线之前要经过安全测试,安全测试中有这么一项,请求头中的host字段,这个值随便修改之后,响应还可以正常返回,这种这种就是有风险的,是测试不通过的,默认情况下,浏览器地址栏中的URL和请求头中的host字段值的ip和端口(或者是域名)是一样的&a…...
vue3实现router路由
说明: vue3实现router路由 效果图: step1:项目结构 src/ ├── views/ │ ├── Home.vue │ └── User.vue ├── router/ │ └── index.js ├── App.vue └── main.jsstep2:左边路由列表C:\Users\wangrusheng\PycharmProjects\un…...
蓝桥杯省赛 棋盘 3533 二维差分+二维前缀和
传送门 0棋盘 - 蓝桥云课 const int N 2e3 10;int n,m; int a[N][N];void insert(int x11,int y11,int x22,int y22) {a[x11][y11] ;a[x11][y22 1] --;a[x22 1][y11] --;a[x22 1][y22 1] ; }void solve() {cin >> n >> m;for (int i 1;i < m;i ){int x11…...
1500 字节 MTU | 溯源 / 技术权衡 / 应用影响
注:本文为 “MTU 字节” 相关文章合辑。 机翻,未校。 讨论部分,以提交人为分界。 单行只有阿拉伯数字的,为引文转译时对回复的点赞数。 How 1500 bytes became the MTU of the internet 1500 字节是如何成为互联网 MTU 的 Fe…...
智能仪表板DevExpress Dashboard v24.2新版亮点:支持.NET 9
使用DevExpress BI Dashboard,再选择合适的UI元素(图表、数据透视表、数据卡、计量器、地图和网格),删除相应参数、值和序列的数据字段,就可以轻松地为执行主管和商业用户创建有洞察力、信息丰富的、跨平台和设备的决策…...
【数据结构】二叉树的递归
数据结构系列三:二叉树(二) 一、递归的原理 1.全访问 2.主角 3.返回值 4.执等 二、递归的化关系思路 三、递归的方法设计 一、递归的原理 1.全访问 方法里调用方法自己,就会形成调用方法本身的一层一层全新相同的调用,方法的形参设置…...
