首页 > 其他分享 >超级实用!React-Router v6实现页面级按钮权限

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

时间:2023-10-03 20:22:41浏览次数:51  
标签:const React meta v6 按钮 Router 权限 路由 页面

大家好,我是王天~

今天咱们用 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

标签:const,React,meta,v6,按钮,Router,权限,路由,页面
From: https://www.cnblogs.com/wangtianzhen/p/17741594.html

相关文章

  • 什么是 Angular 14 的 strict typing of Angular Reactive Forms
    Angular14引入的"stricttypingofAngularReactiveForms"是一项强大的功能,它进一步提高了Angular应用程序的类型安全性和可维护性,特别是在处理表单时。这个功能使开发人员能够更精确地定义表单控件和表单模型的类型,从而减少了潜在的运行时错误,并提供了更好的代码提示和文......
  • React
    React是Facebook开发的一款JS库,那么Facebook为什么要建造React呢,主要为了解决什么问题,通过这个又是如何解决的?从这几个问题出发我就在网上搜查了一下,有这样的解释。Facebook认为MVC无法满足他们的扩展需求,由于他们非常巨大的代码库和庞大的组织,使得MVC很快变得非常复复杂,每当需要......
  • [react性能优化]--防止react-re-render: Why Suspense and how ?
    近期内部项目基础项目依赖升级,之前使用的路由缓存不再适用,需要一个适配方案。而在此过程中reactre-render算是困扰了笔者很久。后来通过多方资料查找使用了freeze解决了此问题。本文主要论述reactre-render问题一般的解决方案和freeze在react内部的实现原理。react版本17.0.2......
  • React 18 useEffect 代码执行两次的问题
    https://github.com/zjy4fun/notes/issues/62 React18提出的新特性“并发渲染”,为了防止组件重复挂载的问题,React在开发模式&&严格模式下,useEffect会执行两次(模拟组件挂载和组件卸载,让问题提早暴露),但是线上模式不会。开发模式下,可以通过设置标志位防止useEffect执行多......
  • react中受控组件与非受控组件
    受控组件与非受控组件受控组件:其值由React控制的组件,通常使用state来控制和修改组件的值。例如受控的组件:classNameFormextendsReact.Component{constructor(props){super(props);this.state={value:''};}handleChange=(event)=>{thi......
  • 理解React页面渲染原理,如何优化React性能?
    ReactJSX转换成真实DOM过程当使用React编写应用程序时,可以使用JSX语法来描述用户界面的结构。JSX是一种类似于HTML的语法,但实际上它是一种JavaScript的扩展,用于定义React元素。React元素描述了我们想要在界面上看到的内容和结构。在运行React应用程序时,JSX会被转换成真实的DOM元素......
  • 前端 | 如何处理 React18 componentDidMount 重复执行两次的问题 | React
    前端|如何处理React18componentDidMount重复执行两次的问题|React问题描述按照React官网推荐方式创建项目,在运行项目的时,发现组件的componentDidMount方法被触发了两次。但是在旧项目中并没有这样的问题,于是觉得奇怪,以为是自己哪里使用错了,一直在排查。经过查阅官方文......
  • 前端 | React setState 同步异步以及处理方式 | React
    前端|ReactsetState同步异步以及处理方式|React问题描述在同步执行流程中setState表现为异步,而在异步执行流程中setState表现为同步。示例:有一个控制DOM节点显隐的状态值,默认为false,而下一步就需要获取该DOM节点做一系类处理。所以一开始使用setState设置状态值为true,让该......
  • js:创建一个基于vite 的React项目
    相关文档Vite官方中文文档React中文文档ReactRouterRedux中文文档AntDesign5.0AwesomeReact创建vite+react项目pnpmcreatevitereact-app--templatereact#根据提示,执行命令cdreact-apppnpminstallpnpmrundev项目结构$tree-L1.├──README.md├──......
  • Java:Springboot和React中枚举值(数据字典)的使用
    目录1、开发中的需求2、实现效果3、后端代码4、前端代码5、接口数据6、完整代码7、参考文章1、开发中的需求开发和使用过程中,通常会涉及四个角色:数据库管理员、后端开发人员、前端开发人员、浏览者数据库使用int类型的数值进行存储(eg:0、1、2)Java代码使用enum枚举类型的对象进行......