大家好,我是王天~

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

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

前言

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

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

实现思路

按钮控制本质是条件判断,满足条件显示按钮,否则禁用/消失。

假如每个页面的按钮权限都不同,简单的条件判断,肯定无法满足,那如何实现呢 ?

王天觉得重点是权限数据结构,如何获取当前页面的按钮权限数据,这需要和后端沟通好,定义页面路径和权限数据的映射关系

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

步骤:

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

实战代码

定义路由配置数据

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

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

既然无法通过路由实例获取权限数据,那么我们手动创建一个对象,来存储路由和按钮权限映射关系。

用户登录后,在遍历生成路由配置同时、将按钮权限和页面路径的映射数据,存储本地。

执行如下代码

按钮权限组件

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

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>

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

效果:

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



以上全文完,最后总结一下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中 无法自定义路由属性,报错日志如下

感谢阅完~

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

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

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

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

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

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

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

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

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

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

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

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

超级实用!React-Router v6实现页面级按钮权限的更多相关文章

  1. React+React Router+React-Transition-Group实现页面左右滑动+滚动位置记忆

    2018年12月17日更新: 修复在qq浏览器下执行pop跳转时页面错位问题 本文的代码已封装为npm包发布:react-slide-animation-router 在React Router中,想 ...

  2. vue基于页面中按钮权限控制

    main.js // 权限 /** 权限指令,对按钮权限的控制 **/ Vue.directive('allow', { bind: function(el, binding) { // 通过当前按钮 ...

  3. React Router v4 页面传值的三种方法

    传值方法 1.props.params 使用React router定义路由时,我们可以给指定一个path,然后指定通配符可以携带参数到指定的path: <Route path='/user/: ...

  4. React Router基础使用

    React是个技术栈,单单使用React很难构建复杂的Web应用程序,很多情况下我们需要引入其他相关的技术 React Router是React的路由库,保持相关页面部件与URL间的同步 下面就来简单 ...

  5. React Router 4.x 开发,这些雷区我们都帮你踩过了

    前言 在前端框架层出不穷的今天,React 以其虚拟 DOM .组件化开发思想等特性迅速占据了主流位置,成为前端开发工程师热衷的 Javascript 库.作为 React 体系中的重要组成部分:Re ...

  6. React Router API文档

    React Router API文档 一.<BrowserRouter> 使用HTML5历史记录API(pushState,replaceState和popstate事件)的<Rou ...

  7. React Router基础教程

    React是个技术栈,单单使用React很难构建复杂的Web应用程序,很多情况下我们需要引入其他相关的技术 React Router是React的路由库,保持相关页面部件与URL间的同步 下面就来简单 ...

  8. React Router 4.0 + webpack 实现组件按需加载

    网上关于React Router 4.0的按需加载文章有很多,大致的思路都一样,但是其实具体实现起来却要根据自己的实际情况来定,这里主要介绍一下我的实现方式. 主要方式是通过Route组件的rende ...

  9. React躬行记(13)——React Router

    在网络工程中,路由能保证信息从源地址传输到正确地目的地址,避免在互联网中迷失方向.而前端应用中的路由,其功能与之类似,也是保证信息的准确性,只不过来源变成URL,目的地变成HTML页面. 在传统的前端 ...

  10. [转] React Router 使用教程

    PS:react-route就是一个决定生成什么父子关系的组件,一般和layout结合起来,保证layout不行,内部的子html进行跳转 你会发现,它不是一个库,也不是一个框架,而是一个庞大的体系. ...

随机推荐

  1. matlab转C++——C++中的矩阵运算和矩阵型函数

    最近接到一个委托,把matlab代码转译为c++语言,看看能不能提高运行效率. matlab虽然本身具有将程序转化为C++的app库,但是对代码格式有严格的要求: 变量使用之前需要对变量类型和空间大小 ...

  2. PHP支付接口签名生成数据

    <?php //作者主页 https://www.woailunwen.com $pay_memberid = '商户号'; $pay_orderid = '订单号'; $pay_amount ...

  3. Codeforces Round #877 (Div. 2) A-E

    A 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; bool solve() { int n; ...

  4. 关于SQL SERVER ROW_NUMBER(),RANK(),DENSE_RANK() 的排序和分页查询问题

    经常接触SQL SERVER 的朋友来说,排序是经常遇见的问题,有的人还会傻傻自己写排序,比如用循环去写,当然这就比较难受 今天就给大家介绍一下SQL SERVER 自带的排序,共有三种,分别为ROW ...

  5. 基于JavaFX的扫雷游戏实现(四)——排行榜

      这期看标题已经能猜到了,主要讲的是成绩排行功能,还有对应的文件读写.那么废话不多说,让我们有请今天的主角...的设计稿:   那么主角是何方神圣呢?当然是图中的大框框--TableView.关于这 ...

  6. System类_Calendar类_Date类_小记

    PrintStream(字节打印流) ps = System.out ; 标准输出流 PrintWriter(字符打印流) InputStream in = System.in; 标准输入流 常用的成 ...

  7. 详解prettier使用以及与主流IDE的配合

    很多前端小伙伴在日常使用prettier的时候都或多或少有一点疑惑,prettier在每一个IDE中究竟是怎样工作起来的,为什么配置有时候生效,有时又毫无效果.为了让我们的前端小伙伴更加熟悉这块,本文 ...

  8. 通过Jmeter压测存储过程

    通过Jmeter压测存储过程 一.存储过程准备: 1.建立一个空表: CREATE TABLE test_data ( id NUMBER, name VARCHAR2(50), age NUMBER ...

  9. Redis的设计与实现-总结

    个人真的很喜欢这本书, 从对C语言一窍不通, 到发现C语言竟然如此简洁, 以至于我喜欢上了C! 对此前面的底层数据结构也读了几次, 大致整理了书里的内容, 后面的就粗略看了一下, 不再细细整理了. R ...

  10. JDK源码-StringJoiner源码分析

    背景 功能描述:将多个元素使用指定符号前后连接为字符串:eg:1 2 3 4 5 , => 1,2,3,4,5 要点: 多个元素 指定分隔符 分隔符只在元素之间,不能作为第一或最后一个 使用方法 ...