大家好,我是王天~
今天我們們用 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
」,加我進王天唯一的讀者群。
個人部落格:https://itwangtian.com