超级实用!React-Router v6实现页面级按钮权限

超级,实用,react,router,v6,实现,页面,按钮,权限 · 浏览次数 : 15

小编点评

**实现思路** 1. 获取当前页面的位置信息,包括路由路径和权限数据。 2. 从本地缓存中获取页面路径和权限数据。 3. 找到当前页的按钮权限数据,并缓存到本地。 4. 根据按钮权限和页面路径,动态控制按钮显隐、禁用或显示。 **代码实现** ```js import { Tooltip } from 'antd'; import React from 'react'; import { useLocation } from 'react-router-dom'; interface IndexProps { scopeTtype: string; // 权限码 children: any // 子组件 } const Index: React.FC<IndexProps> = (props) => { const routeDom = useLocation(); const strPersstion = localStorage.getItem('pagePersstion'); const pagePersstion = JSON.parse(strPersstion as string); // 找到当前页的按钮权限数据 const currentPerssion = pagePersstion.find((item: { page: string; }) => item.page == routeDom.pathname); // 组件渲染逻辑 if (currentPerssion && currentPerssion.permissions[props.scopeTtype]) { return props.children; } else { return ( ); } }; export default Index; ``` **踩坑记录** 1. 在react-router6版本中,无法自定义路由属性,无法获取路由的信息。 2. 在获取页面权限数据时,需要手动创建一个对象存储路由和按钮权限映射关系。 3. 在组件中使用useRoutes()钩子获取路由传递的属性,可能存在兼容问题。

正文

大家好,我是王天~

今天咱们用 reac+reactRouter来实现页面级的按钮权限功能。这篇文章分三部分,实现思路、代码实现、踩坑记录。

嫌啰嗦的朋友,直接拖到第二章节看代码哦。

前言

通常情况下,咱们为用户添加权限时,除了页面权限,还会细化到按钮级别,比如、新增、删除、查看等权限。

如下效果,切换用户登录后,操作权限除了左侧菜单,还有页面按钮。
按钮权限演示效果.gif

实现思路

按钮控制本质是条件判断,满足条件显示按钮,否则禁用/消失。
假如每个页面的按钮权限都不同,简单的条件判断,肯定无法满足,那如何实现呢 ?
王天觉得重点是权限数据结构,如何获取当前页面的按钮权限数据,这需要和后端沟通好,定义页面路径和权限数据的映射关系

使用路由实现页面按钮权限

步骤:

  1. 在路由配置中添加页面权限参数
  2. 通过路由实例,获取当前页的权限
  3. 封装按钮权限组件,动态显隐按钮

实战代码

定义路由配置数据

需和后端配合,将按钮权限和页面路由一同返回
image.png

存储路由和按钮权限映射关系

既然无法通过路由实例获取权限数据,那么我们手动创建一个对象,来存储路由和按钮权限映射关系。
用户登录后,在遍历生成路由配置同时、将按钮权限和页面路径的映射数据,存储本地。
执行如下代码
image.png

按钮权限组件

封装按钮权限组件,读取本地权限数据、控制按钮的显隐、禁用状态,代码如下:

import { Tooltip } from 'antd';
import React from 'react';
import { useLocation } from 'react-router-dom';

interface IndexProps {
  scopeTtype:string, // 权限码
  children:any// 子组件
}

const Index: React.FC<IndexProps> = (props) => {
  // 获取当前页面的位置信息、
  const routeDom = useLocation(); 
  // 从本地缓存读取 页面路径和权限数据
  const strPersstion = localStorage.getItem('pagePersstion');
  const pagePersstion = JSON.parse(strPersstion as string); 
  // 找到当前页的按钮权限数据
  const currentPerssion = pagePersstion.find((item: { page: string; })=>item.page == routeDom.pathname);
  console.log('当前页面的按钮权限',currentPerssion);
  //  有权限返回按钮
  if(currentPerssion.permissions[props.scopeTtype]){
    return  props.children;
  }else{ 
    // 没有则禁用、或者隐藏按钮
    // 要实现按钮禁用,需要设置组件的disabled 
    // 可是react 中的props是只读无法修改,如何修改props中子组件呢?
    // 通过React API React.cloneElement 克隆出新的元素进行修改如下
    const Button = React.cloneElement(props.children, {
      disabled: true
    });

    return   <>
      <Tooltip title="暂无权限">  {Button}</Tooltip>
    </>;
  };
};


export default Index;

使用按钮权限组件

<AuthButton scopeTtype="isDelete">
  <Button type="primary" onClick={start} disabled={!hasSelected} loading={loading}>
    批量删除
  </Button>
</AuthButton>
<AuthButton scopeTtype="isAdd">
    <Button onClick={showModal}>新增员工</Button>
</AuthButton>

模拟的路由数据:员工管理页面的路由、按钮配置
image.png

效果:

当切换用户登录后,很明细发现右侧表格、操作按钮权限变化。效果如下

以上全文完,最后总结一下reactRoute和vueRouter的实现区别。

vueRouter vs ReactRouter

vueRouter

此方案中,在vue中实现比较方便,使用vueRouter配置路由meta元信息、为按钮权限的数据

{
  path: '/imgMove/:id',
    name: 'imgMove',
    meta: {
    itwangtianAuth: true
    // 此页面是否token校验
  },
  component: imgMove
}

在页面路由实例中读取meta数据,进行页面级别的按钮权限控制。

// 在 Vue 组件中获取路由的 meta 数据
export default {
  name: 'ExampleComponent',
  mounted() {
    // 获取当前路由对应的路由记录
    const route = this.$route; 
    // 获取该路由记录的 meta 数据
    const meta = route.meta; 
    // 使用 meta 数据
    console.log(meta.itwangtianAuth); 
  }
}

ReactRouter

但是,在react-Router6版本中没有路由元信息配置,就算自定义路由属性,也无法获取,如下是踩坑代码,大家看看就行、可不要尝试了

踩坑记录

踩坑代码-添加路由自定义属性,获取权限数据首先,在路由配置中设置自定义属性,例如 title 和 requiresAuth:

<Route
  path="/dashboard"
  element={<Dashboard />}
  title="Dashboard"
  requiresAuth={true}
  />

然后,在 Dashboard 组件中可以通过 useRoutes() 钩子获取路由传递的属性,如下所示:

import { useRoutes, useParams, useNavigate } from 'react-router-dom';

function Dashboard() {
  const params = useParams();
  const navigate = useNavigate();

  // 访问路由传递的属性
  const { title, requiresAuth } = useRoutes().pathname;

  // 在这里使用元信息进行逻辑处理

  return (
    <div>
      <h1>{title}</h1>
      {/* 组件的其余部分 */}
    </div>
  );
}

结果不用说了,报错啊啊啊啊啊啊啊
在react-route6中 无法自定义路由属性,报错日志如下
image.png

感谢阅完~

读者朋友好呀,我是王天~

尝试做过很多事情,汽修专业肄业生,半路出道的野生程序员、前端讲师、新手作者,最终还是喜欢写代码、乐于用文字记录热衷分享~

如文章有错误或者不严谨的地方,期待给于指正,万分感谢。

如果喜欢或者 有所启发,欢迎 star,对作者也是一种鼓励。

微信:「wangtian3111」,加我进王天唯一的读者群。

个人博客:https://itwangtian.com

与超级实用!React-Router v6实现页面级按钮权限相似的内容:

超级实用!React-Router v6实现页面级按钮权限

大家好,我是王天~ 今天咱们用 reac+reactRouter来实现页面级的按钮权限功能。这篇文章分三部分,实现思路、代码实现、踩坑记录。 嫌啰嗦的朋友,直接拖到第二章节看代码哦。 前言 通常情况下,咱们为用户添加权限时,除了页面权限,还会细化到按钮级别,比如、新增、删除、查看等权限。 如下效果,

CSS3 超实用属性:pointer-events (可穿透图层的鼠标事件)

1、是什么 pointer-events 直译为指针事件,该属性指定在什么情况下某个DOM可以成为鼠标事件的 target。 简而言之,就是允许/禁止DOM的鼠标事件(click事件、hover事件、mouse事件等鼠标事件) 2、具体属性分析 用法分析:pointer-events: auto |

开发者需掌握的超实用VS Code for Windows快捷键

链接|https://dev.to/devland/100-crucial-keyboard-shortcuts-for-vs-code-users-4474 作者|Thomas Sentre 翻译|Seal软件 原文作者已授权。 在软件开发的世界里时间是非常宝贵的。随着项目的堆积和发布日期的临近,

可视化—gojs 超多超实用经验分享(四)

目录41.监听连线拖拽结束后的事件42.监听画布的修改事件43.监听节点被 del 删除后回调事件(用于实现调用接口做一些真实的删除操作)44.监听节点鼠标移入移出事件,hover 后显示特定元素45.监听树图实现鼠标点击节点本身展开或收起子节点的功能,而不是点击另外的按钮46.监听文本块编辑结束后

可视化—gojs 超多超实用经验分享(三)

目录32.go.Palette 一排放两个33.go.Palette 基本用法34.创建自己指向自己的连线35.设置不同的 groupTemplate 和 linkTemplate36.监听在图形对象 GraphObject 上的右键单击37.定义节点/连线/canvas 背景上的右键菜单38.从节

干货!超实用的 Linux 初始化脚本

咸鱼今天给大家分享一个无论是学习还是工作中都很实用的 Linux 系统初始化脚本,其实就是各种命令的集合 完整代码在文章最后哦 定义相关变量 配置 yum 镜像源 获取阿里云 yum 镜像源 判断函数是否执行成功 写入一行配置 修改配置 配置系统时区 配置 dns 服务器 修改最大文件描述符限制 关

技术解密Java Chassis 3超实用的可观测性

本文分享自华为云社区《Java Chassis 3技术解密:实用的可观测性》,作者:liubao68。 狭义的可观测性,指日志、调用链和指标,广义的可观测性则包含更多的内容,一般的,应用程序暴露出来的便于理解其运行状态、运行轨迹、内部结构和功能集合的信息,都是可观测性的范围,本文只讨论狭义的可观测性

NPM 实用命令与快捷方式

在 JavaScript 中,无论是新手还是专家都可能在命令行中使用过 NPM。在本篇文章中,我将会整理超实用的 NPM 命令、快捷方式及技巧,帮助 JavaScript 开发人员提高生产力和效率。 在这篇文章中,我们将涵盖以下主题: npm 的定义。 使用 npm 包管理系统管理应用程序依赖项,来

Springboot简单功能示例-1 实现基本WEB服务

博主尝试通过gitee的发行版,使用Springboot为基础框架,逐步整合JWT、JPA、VUE等常用功能项目。 其中博主还将尝试统一异常处理、自定义加密认证、代码自动生成等功能

Springboot简单功能示例-3 实现基本登录验证

博主尝试通过gitee的发行版,使用Springboot为基础框架,逐步整合JWT、JPA、VUE等常用功能项目。【本节完成】使用spring-security6.1.3,抛弃了WebSecurityConfigurerAdapter的配置方式,直接使用session实现基本的登录验证功能