大家好,我是王天~ 今天咱們用 reac+reactRouter來實現頁面級的按鈕許可權功能。這篇文章分三部分,實現思路、代碼實現、踩坑記錄。 嫌啰嗦的朋友,直接拖到第二章節看代碼哦。 前言 通常情況下,咱們為用戶添加許可權時,除了頁面許可權,還會細化到按鈕級別,比如、新增、刪除、查看等許可權。 如下效果, ...
大家好,我是王天~
今天咱們用 reac+reactRouter來實現頁面級的按鈕許可權功能。這篇文章分三部分,實現思路、代碼實現、踩坑記錄。
嫌啰嗦的朋友,直接拖到第二章節看代碼哦。
前言
通常情況下,咱們為用戶添加許可權時,除了頁面許可權,還會細化到按鈕級別,比如、新增、刪除、查看等許可權。
如下效果,切換用戶登錄後,操作許可權除了左側菜單,還有頁面按鈕。
實現思路
按鈕控制本質是條件判斷,滿足條件顯示按鈕,否則禁用/消失。
假如每個頁面的按鈕許可權都不同,簡單的條件判斷,肯定無法滿足,那如何實現呢 ?
王天覺得重點是許可權數據結構,如何獲取當前頁面的按鈕許可權數據,這需要和後端溝通好,定義頁面路徑和許可權數據的映射關係
使用路由實現頁面按鈕許可權
步驟:
- 在路由配置中添加頁面許可權參數
- 通過路由實例,獲取當前頁的許可權
- 封裝按鈕許可權組件,動態顯隱按鈕
實戰代碼
定義路由配置數據
需和後端配合,將按鈕許可權和頁面路由一同返回
存儲路由和按鈕許可權映射關係
既然無法通過路由實例獲取許可權數據,那麼我們手動創建一個對象,來存儲路由和按鈕許可權映射關係。
用戶登錄後,在遍歷生成路由配置同時、將按鈕許可權和頁面路徑的映射數據,存儲本地。
執行如下代碼
按鈕許可權組件
封裝按鈕許可權組件,讀取本地許可權數據、控制按鈕的顯隱、禁用狀態,代碼如下:
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
」,加我進王天唯一的讀者群。