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

React新闻发布系统 权限列表开发

本章内容:1.开发思路 2.页面开发

一:开发思路

这是整个组件的开发思路 我们主要聚焦于权限列表部分。主要功能有两个,删除权限(删除按钮)和配置开关(编辑按钮) 其中删除权限的逻辑是拿到我们需要删除的行数据 然后记录下来依次修改前端页面 和 后端json数据通过axios的delete请求删除数据。配置开关的逻辑也差不多 ,还是拿到要操作的数据 依次修改前后端数据

二:静态页面开发

(1)效果图与table组件

在写代码之前来看看这个页面的效果是什么

静态页面的效果 下面是点击编辑按钮之后弹出的swith选择器

下面是点击删除按钮之后弹出的确定框 

在页面中我们主要使用的组件是Antd提供的Table组件 作为页面的基础。先来看看Table组件

这里我们给出两组基础数据 1.dataSource是未来我们从后端拿去的数据 2.columns表示我们设定的行列表头。

在数据中 dataIndex表示将来哪一项显示在table组件中 key表示唯一标识 是用来确保React正确高效的渲染页面

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} />;

来看看效果:

来看看权限列表组件的return部分:

return (<div>{/* antd表格 如果设置的数据中存在children属性 就会默认使用树形数据展示 */}<Table dataSource={dataSource} columns={columns} pagination={{pageSize:5}}/></div>)

其中pagination中表示我们一页可以渲染几个子项 如果超出就自动分页。

现在我们给出我们需要使用的columns数据 这个数据是一个数组 这里给出的只是基础的行列模式,观看效果图可知还有两个按钮未实现。

const columns = [{title: 'ID',dataIndex: 'id',key: 'id',},{title: '权限名称',dataIndex: 'label',key: 'label',},{title: '权限路径',dataIndex: 'key',key: 'key',render:(key)=>{return  <Tag color="gold">{key}</Tag>}}];

(2)column操作按钮实现

现在我们在原本column的基础上实现两个按钮。

首先是实现选择按钮的组件 我们使用的是Popover气泡卡片组件 这个组件可以在点击之后弹出一个不影响其他组件运行的弹出框。在该组件的属性值中设置好气泡的标题,trigger属性是用来确定这个卡片会不会点击弹出的 如果数据汇总item.pageperssion属性不存在就设置为不可点击,在content属性中我们用div包裹一个switch组件 switch组件是一个开关按钮组件。在switch组件汇总 checked是一个布尔值的属性 用来判定switch开关是默认打开还是关闭 onclick中就是我们的操作逻辑 用来控制前端页面的刷新和后端数据的更新。 下面的BUTTON按钮就是用来判定卡片是否弹出的关键按钮了。

下面的删除按钮则是使用Popconfirm气泡确定框来包裹,用来判定是否删除数据,确保按钮不会被用户误触。 其中的onConfirm中就是处理确认删除的,前后端数据处理的逻辑函数

[...codes,{title: '操作',render:(item)=>{// item就是当前行return (<><Popover title="权限状态" trigger={item.pagepermisson==undefined?'':'click'} content={<div style={{textAlign:'center'}} >{/* switch组件的选择与否 是后台传入数据决定的 */}<Switch checked={item.pagepermisson} onClick={()=>{switchPermission(item)}}/></div>} ><Button icon={<EditOutlined color='blue'/>} shape='circle' color='blue' disabled={item.pagepermisson==undefined}></Button></Popover><Popconfirmtitle="确定删除吗?"okText="确定"cancelText="取消"onConfirm={()=>{confirmDelete(item)}}><Button icon={<DeleteOutlined/>} shape='circle' danger></Button></Popconfirm></>)}}
]

三:逻辑代码与处理函数

(1)从后端获取列表数据

我们主要使用axios插件来从后端获取数据,因为这是一个异步数据请求操作,建议还是当场一个副作用处理函数 避免阻塞静态页面的渲染。首先我们需要将后端获取的数据设置成一个状态,确保后端数据被修改后能被成功再次获取。

在useEffect中创建一个异步函数来从后端获取数据 然后通过判断将首页数据的children数据设置成null避免影响table表格中 home子项出现树状数据按钮(就是表头那个小加号)。然后将获取来的数据设置给dataSource

//未来动态从后端获取 所以设置成状态比较合理const [dataSource,setDataSource]=useState([])//获取渲染数据useEffect(()=>{const getRightList=async ()=>{const res=await axios.get('http://localhost:3000/rights?_embed=children')if(res.data[0].children.length===0){res.data[0].children=null}setDataSource(res.data)}getRightList()},[])

(2)确然删除逻辑与Switch状态修改逻辑

首先还请大家注意到在columns表头数据中,render渲染函数中我们设置了一个item的参数 这个参数其实就是我们点击table里面的某一行的数据 是一个对象

所以item就给了我们操作数据的基础了

删除逻辑

我们先来写删除逻辑 就是点击删除按钮后在弹出框点击确定后的逻辑。

首先处理前端状态 通过filter过滤函数将我们点击的那行从原始数据中筛查出去并重新设置datasource的状态。 在处理后端数据的时候 我们首先需要将数据分级 item数据存在一个grade属性 表示当前数据属于一级子项 我们可以直接通过axios的delete方法将这个数据从数据中删除。比较麻烦的是二级子项 设置一个新list获取dataSource数据中id和点击子项item的children属性中rightdid相等的那一项 就是获取点击子项的父项 因为这个父项只可能有一个元素 所以操作list的第一个元素 将点击item从这个筛出来的父项中去除 然后重新更新dataSource刷新页面,最后通过axios删除数据。

  const confirmDelete=(item)=>{console.log(item);// 先删除前端状态setDataSource(dataSource.filter(data=>data.id!==item.id))//二级子项数据删除if(item.grade===1){axios.delete(`http://localhost:3000/rights/${item.id}`).then((err)=>{if(err){console.log(err);}})}else{let list=dataSource.filter(data=>data.id===item.rightId)// console.log(list);list[0].children=list[0].children.filter(data=>data.id!==item.id)setDataSource([...dataSource])axios.delete(`http://localhost:3000/children/${item.id}`)}}
开关逻辑

这个逻辑相较于删除逻辑要简单许多

这里我们不需要查找了,直接操作item点击数据就可以。首先是将pagepermisson取反 如果是1就设置成0 取反之后更新数据 这样前端页面就会重新刷新。 在继续分级来操作后端数据 这里就比较简单来 直接通过patch请求方法来更新后端数据就行了(之所以不用筛选是因为这里我们直接操作的是children的后端数据,而不是操作rights?_embed=childre的联查数据)

//不用查找了 直接配置item就行const switchPermission=(item)=>{ //控制前端的状态item.pagepermisson=item.pagepermisson===1?0:1;setDataSource([...dataSource])//用来触发重新渲染 数组还是那个数组// 控制权限状态 分为一级权限和二级权限 控制后端的pagepermissonif(item.grade===1){// 使用patch请求(补丁更新) 只更新pagepermissonaxios.patch(`http://localhost:3000/rights/${item.id}`,{//item.pagepermisson在前端状态的时候已经更新了pagepermisson:item.pagepermisson})}else{axios.patch(`http://localhost:3000/children/${item.id}`,{pagepermisson:item.pagepermisson})}}

四:源代码

最后附上源代码

import React, { useEffect, useState } from 'react'
import {Button, Table,Tag,Popconfirm,Popover,Switch} from 'antd';
import axios from 'axios';
import{ DeleteOutlined,EditOutlined
}from '@ant-design/icons'
export default function RightList() {//未来动态从后端获取 所以设置成状态比较合理const [dataSource,setDataSource]=useState([])//获取渲染数据useEffect(()=>{const getRightList=async ()=>{const res=await axios.get('http://localhost:3000/rights?_embed=children')if(res.data[0].children.length===0){res.data[0].children=null}setDataSource(res.data)}getRightList()},[])const columns = [{title: 'ID',dataIndex: 'id',key: 'id',},{title: '权限名称',dataIndex: 'label',key: 'label',},{title: '权限路径',dataIndex: 'key',key: 'key',render:(key)=>{return  <Tag color="gold">{key}</Tag>}},{title: '操作',render:(item)=>{// item就是当前行return (<><Popover title="权限状态" trigger={item.pagepermisson==undefined?'':'click'} content={<div style={{textAlign:'center'}} >{/* switch组件的选择与否 是后台传入数据决定的 */}<Switch checked={item.pagepermisson} onClick={()=>{switchPermission(item)}}/></div>} ><Button icon={<EditOutlined color='blue'/>} shape='circle' color='blue' disabled={item.pagepermisson==undefined}></Button></Popover><Popconfirmtitle="确定删除吗?"okText="确定"cancelText="取消"onConfirm={()=>{confirmDelete(item)}}><Button icon={<DeleteOutlined/>} shape='circle' danger></Button></Popconfirm></>)}}];const confirmDelete=(item)=>{console.log(item);// 先删除前端状态setDataSource(dataSource.filter(data=>data.id!==item.id))//二级子项数据删除if(item.grade===1){axios.delete(`http://localhost:3000/rights/${item.id}`).then((err)=>{if(err){console.log(err);}})}else{let list=dataSource.filter(data=>data.id===item.rightId)// console.log(list);list[0].children=list[0].children.filter(data=>data.id!==item.id)setDataSource([...dataSource])axios.delete(`http://localhost:3000/children/${item.id}`)}}//不用查找了 直接配置item就行const switchPermission=(item)=>{ //控制前端的状态item.pagepermisson=item.pagepermisson===1?0:1;setDataSource([...dataSource])//用来触发重新渲染 数组还是那个数组// 控制权限状态 分为一级权限和二级权限 控制后端的pagepermissonif(item.grade===1){// 使用patch请求(补丁更新) 只更新pagepermissonaxios.patch(`http://localhost:3000/rights/${item.id}`,{//item.pagepermisson在前端状态的时候已经更新了pagepermisson:item.pagepermisson})}else{axios.patch(`http://localhost:3000/children/${item.id}`,{pagepermisson:item.pagepermisson})}}return (<div>{/* antd表格 如果设置的数据中存在children属性 就会默认使用树形数据展示 */}<Table dataSource={dataSource} columns={columns} pagination={{pageSize:5}}/></div>)
}

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

相关文章:

  • 23种设计模式之【策略模式】-核心原理与 Java 实践
  • 前端实战从零构建响应式井字棋游戏
  • Java中的equals()与hashCode()
  • 【绕过open_basedir】
  • 如何用户细分
  • 福彩双色球第2025109期篮球号码分析
  • 思考:客户端负载均衡和服务器负载均衡有什么区别?
  • 网络编程day04/05原始套接字
  • Yarn命令与npm命令的区别与联系(npm:Node.js的官方包管理工具;Yarn:Facebook开发的JavaScript包管理工具)
  • 【大语言模型 67】梯度压缩与稀疏通信
  • LeetCode第365题_水壶问题
  • OpenCV:DNN 模块实现图像风格迁移
  • 锤子助手插件功能六十四:禁用视频前置摄像头镜像
  • OpenHarmony NFC Tag驱动深度剖析:从HDF框架到NDEF读写全流程实战
  • 黑马头条_SpringCloud项目阶段四:多媒体短文章提交功能实现详解
  • TraceID串联数据孤岛:勤源全链路可观测性平台破解微服务“黑箱困境”
  • 随机梯度下降(SGD)算法及其在机器学习中的应用
  • 趣谈bug - the Norway problem
  • $attrs 和 $listeners 的使用场景和用法是什么?
  • [Linux]学习笔记系列 -- lib/radix-tree.c 基数树(Radix Tree) 整数键到指针的高效映射
  • Scikit-learn Python机器学习 - 回归分析算法 - 线性回归 (LinearRegression SGDRegressor)
  • ts的内置工具类型
  • 扫地车:守护多元场景的清洁 “多面手”
  • 力扣 136.只出现一次的数字
  • 【序列晋升】38 Spring Data MongoDB 的统一数据访问范式与实践
  • 如何将枯燥的大数据呈现为可视化的图和动画?
  • 前后端分离架构下,如何安全存储和使用 API 密钥?
  • Nano 编辑器快捷键
  • 《智能体教程》——如何构建多智能体系统:开发者实用指南
  • 小杰机器学习高级(three)——逻辑回归、二分类算法