最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React?組件權(quán)限控制的實(shí)現(xiàn)

 更新時(shí)間:2022年02月14日 08:31:52   作者:Pwcong  
本文主要介紹了React?組件權(quán)限控制的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前話

具備用戶體系的業(yè)務(wù)系統(tǒng)往往需要具備權(quán)限控制的能力。前后不分離的開發(fā)模式權(quán)限控制主要由后端結(jié)合模版引擎實(shí)現(xiàn),而前后分離的開發(fā)模式由前后兩端協(xié)商權(quán)限配置分別進(jìn)行數(shù)據(jù)權(quán)限控制和組件權(quán)限控制。

正文

權(quán)限配置格式不限,為進(jìn)行后續(xù)演示本篇設(shè)定權(quán)限配置如下:

export type IAuthConfig = {
? /** 權(quán)限標(biāo)識(shí)列表 */
? keys: string[];
};

且提供一個(gè)Hook直接獲取當(dāng)前用戶信息:

export type IUser = {
? /** 權(quán)限配置 */
? authConfig: IAuthConfig;
};

/** 用戶信息Hook */
export function useUser() {
? // ...略
? return user;
}

首先我們先定義一個(gè)權(quán)限Hook,內(nèi)容如下:

/**
?* 轉(zhuǎn)換為權(quán)限標(biāo)識(shí)數(shù)組
?* @param auth 權(quán)限標(biāo)識(shí)
?* @returns
?*/
function getAuthKeys(auth: string | string[]) {
? return Array.isArray(auth) ? auth : [auth];
}

/** 權(quán)限鑒權(quán)類型 */
export enum EAuthType {
? /** 或權(quán)限(至少匹配一個(gè)) */
? "some" = "some",
? /** 與權(quán)限(全部匹配) */
? "every" = "every",
}

/** 權(quán)限Hook */
export function useAuth() {
? const { authConfig } = useUser();

? // 權(quán)限標(biāo)識(shí)列表
? const authKeys = useMemo(() => authConfig?.keys ?? [], [authConfig]);
? // 校驗(yàn)是否具備權(quán)限
? const hasAuth = useCallback(
? ? (auth: string | string[], type?: EAuthType) =>
? ? ? getAuthKeys(auth)[type ?? EAuthType.every]((key) =>
? ? ? ? authKeys.includes(key)
? ? ? ),
? ? [authKeys]
? );

? const ret: [typeof authKeys, typeof hasAuth] = [authKeys, hasAuth];
? return ret;
}

1. 控制方式

對(duì)于前端開發(fā)而言一般只需做組件控制,控制方式有很多種寫法。

1.1 直接計(jì)算

const Cmpt: React.FC = () => {
? const [, hasAuth] = useAuth();
? // 計(jì)算是否有權(quán)限
? const authorized = useMemo(() => hasAuth("test"), [hasAuth]);

? // ...略
};

1.2 通用權(quán)限Hoc

export function withAuth<P extends Record<string, unknown> = {}>(
? auth: string | string[],
? type?: EAuthType
) {
? return function (Component: any) {
? ? const WrappedComponent: React.FC<P> = (props) => {
? ? ? const [, hasAuth] = useAuth();

? ? ? const instance = React.createElement(Component, {
? ? ? ? ...props,
? ? ? });

? ? ? // 計(jì)算是否有權(quán)限
? ? ? const authorized = hasAuth(auth, type);

? ? ? // ...略
? ? };

? ? WrappedComponent.displayName = `withAuth(${getDisplayName(Component)})`;

? ? return WrappedComponent;
? };
}

1.3 權(quán)限包裹組件

const AuthWrapper: React.FC<IProps> = ({ auth, type, children }) => {
? const [, hasAuth] = useAuth();
? // 計(jì)算是否有權(quán)限
? const authorized = useMemo(() => hasAuth(auth, type), [auth, type, hasAuth]);

? // ...略
};

2. 控制結(jié)果

常見控制結(jié)果為控制組件的顯示或隱藏,或根據(jù)是否具備權(quán)限做組件的自定義渲染。

為方便演示后面統(tǒng)一使用權(quán)限包裹組件進(jìn)行說明。

2.1 顯隱控制

具備權(quán)限的組件直接渲染,否則返回null,即可實(shí)現(xiàn)顯隱控制。權(quán)限包裹組件實(shí)現(xiàn)如下:

const AuthWrapper: React.FC<IProps> = ({ auth, type, children }) => {
? const [, hasAuth] = useAuth();
? // 計(jì)算是否有權(quán)限
? const authorized = useMemo(() => hasAuth(auth, type), [auth, type, hasAuth]);
? // 具備權(quán)限的組件直接渲染,否則返回null
? return authorized ? children : null;
};

在需要權(quán)限控制的組件外包裹權(quán)限組件即可。

const Cmpt: React.FC = () => {
? <>
? ? <AuthWrapper auth="test">
? ? ? <Button>Hello World</Button>
? ? </AuthWrapper>
? </>;
};

2.2 自定義渲染

實(shí)際業(yè)務(wù)場景中,存在需要提醒用戶沒有權(quán)限的情況,這時(shí)需要權(quán)限包裹組件支持自定義渲染,實(shí)現(xiàn)方式有多種:

  • 靜態(tài)props注入
  • 動(dòng)態(tài)props映射
  • render props

相比較之下render props更為自由,權(quán)限包裹組件完善后實(shí)現(xiàn)如下:

type IProps = {
? /** 權(quán)限標(biāo)識(shí) */
? auth: string | string[];
? /** 鑒權(quán)類型 */
? type?: EAuthType;
? /** 子內(nèi)容 */
};

const AuthWrapper: React.FC<IProps> = ({ auth, type, children }) => {
? const [, hasAuth] = useAuth();
? // 計(jì)算是否有權(quán)限
? const authorized = useMemo(() => hasAuth(auth, type), [auth, type, hasAuth]);

? // 自定義渲染
? if (typeof children === "function") {
? ? return children(authorized);
? }

? // 顯隱控制
? return authorized ? children : null;
};

這時(shí)就可以渲染提示無權(quán)限組件:

const Cmpt: React.FC = () => {
? <>
? ? <AuthWrapper auth="test">
? ? ? {(authorized) => <Button disabled={!authorized}>Hello World</Button>}
? ? </AuthWrapper>
? </>;
};

3. 權(quán)限數(shù)據(jù)

前端開發(fā)做組件控制的顆粒度取決于權(quán)限數(shù)據(jù)的類型,權(quán)限數(shù)據(jù)類型分為靜態(tài)權(quán)限和動(dòng)態(tài)權(quán)限。
其中靜態(tài)權(quán)限一般在完成登錄認(rèn)證后即可一次性獲取,而動(dòng)態(tài)權(quán)限則在操作數(shù)據(jù)時(shí)進(jìn)行權(quán)限校驗(yàn)。
因此不難發(fā)現(xiàn)靜態(tài)權(quán)限往往用于控制路由、頁面或者粗糙的操作權(quán)限。而動(dòng)態(tài)權(quán)限則能夠?qū)?dòng)態(tài)數(shù)據(jù)進(jìn)行更細(xì)粒度的操作權(quán)限控制(需后端數(shù)據(jù)權(quán)限控制能力配合)。

3.1 靜態(tài)權(quán)限

如前面描述,登錄認(rèn)證后即可從用戶信息中得到權(quán)限標(biāo)識(shí),同樣前面的栗子均也為靜態(tài)權(quán)限示例。

3.2 動(dòng)態(tài)權(quán)限

需要?jiǎng)討B(tài)權(quán)限校驗(yàn)的場景在業(yè)務(wù)系統(tǒng)中也較為常見,例如用戶能夠看到列表數(shù)據(jù),但禁止查閱無權(quán)限的數(shù)據(jù)詳情。
由此可知對(duì)于用戶而言,獲取的動(dòng)態(tài)的列表數(shù)據(jù)需要逐一進(jìn)行權(quán)限校驗(yàn),這時(shí)我們對(duì)權(quán)限Hook和包裹組件進(jìn)行改造,改造后代碼如下:

type IAuthDynamicConfig = {
? // ...略
};

/** 權(quán)限Hook */
export function useAuth() {
? // ...略

? // 動(dòng)態(tài)校驗(yàn)是否具有權(quán)限
? const dynamicAuth = useCallback(
? ? (auth: string | string[], type?: EAuthType, config?: IAuthDynamicConfig) =>
? ? ? // 批量異步校驗(yàn)權(quán)限,實(shí)現(xiàn)略
? ? ? append2DynamicAuthTask(auth, type, config),
? ? []
? );

? const ret: [typeof authKeys, typeof hasAuth, typeof dynamicAuth] = [
? ? authKeys,
? ? hasAuth,
? ? dynamicAuth,
? ];
? return ret;
}

/** 權(quán)限包裹組件 */
const AuthWrapper: React.FC<IProps> = ({ auth, type, config, children }) => {
? const [, hasAuth, dynamicAuth] = useAuth();

? const [authorized, setAuthorized] = useState(false);

? // 計(jì)算是否有權(quán)限
? useEffect(() => {
? ? if (config === undefined) {
? ? ? setAuthorized(hasAuth(auth, type));
? ? ? return;
? ? }
? ? dynamicAuth(auth, type, config).then(setAuthorized);
? }, [auth, type, config, hasAuth, dynamicAuth]);

? // ...略
};

使用方式如下:

const Cmpt: React.FC = () => {
? // ...略

? <>
? ? {data.map((item) => (
? ? ? <div key={item.id}>
? ? ? ? <div>{item.title}</div>
? ? ? ? <div>
? ? ? ? ? <AuthWrapper
? ? ? ? ? ? auth="detail"
? ? ? ? ? ? config={{
? ? ? ? ? ? ? module: "demo",
? ? ? ? ? ? ? identify: item.id,
? ? ? ? ? ? }}
? ? ? ? ? >
? ? ? ? ? ? {(authorized) => (
? ? ? ? ? ? ? <Button disabled={!authorized} onClick={handleDetail}>
? ? ? ? ? ? ? ? 詳情
? ? ? ? ? ? ? </Button>
? ? ? ? ? ? )}
? ? ? ? ? </AuthWrapper>
? ? ? ? </div>
? ? ? </div>
? ? ))}
? </>;
};

到此這篇關(guān)于React 組件權(quán)限控制的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)React 組件權(quán)限控制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React?函數(shù)式組件和類式組件詳情

    React?函數(shù)式組件和類式組件詳情

    這篇文章主要介紹了React函數(shù)式組件和類式組件詳情,React是組件化的的JS庫,組件化也是React的核心思想,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • React中父子組件通信詳解

    React中父子組件通信詳解

    這篇文章主要介紹了React中父子組件通信詳解,在父組件中,為子組件添加屬性數(shù)據(jù),即可實(shí)現(xiàn)父組件向子組件通信,文章通過圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • React手寫一個(gè)手風(fēng)琴組件示例

    React手寫一個(gè)手風(fēng)琴組件示例

    這篇文章主要為大家介紹了React手寫一個(gè)手風(fēng)琴組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • React hooks使用方法全面匯總

    React hooks使用方法全面匯總

    這篇文章主要介紹了react hooks實(shí)現(xiàn)原理,文中給大家介紹了useState dispatch函數(shù)如何與其使用的Function Component進(jìn)行綁定,實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • react-redux及redux狀態(tài)管理工具使用詳解

    react-redux及redux狀態(tài)管理工具使用詳解

    Redux是為javascript應(yīng)用程序提供一個(gè)狀態(tài)管理工具集中的管理react中多個(gè)組件的狀態(tài)redux是專門作狀態(tài)管理的js庫(不是react插件庫可以用在其他js框架中例如vue,但是基本用在react中),這篇文章主要介紹了react-redux及redux狀態(tài)管理工具使用詳解,需要的朋友可以參考下
    2023-01-01
  • 一文詳解如何使用React監(jiān)聽網(wǎng)絡(luò)狀態(tài)

    一文詳解如何使用React監(jiān)聽網(wǎng)絡(luò)狀態(tài)

    在現(xiàn)代Web應(yīng)用程序中,網(wǎng)絡(luò)連接是至關(guān)重要的,通過監(jiān)聽網(wǎng)絡(luò)狀態(tài),我們可以為用戶提供更好的體驗(yàn),例如在斷網(wǎng)時(shí)顯示有關(guān)網(wǎng)絡(luò)狀態(tài)的信息,本文將介紹如何使用React監(jiān)聽網(wǎng)絡(luò)狀態(tài)的變化,并提供相應(yīng)的代碼示例
    2023-06-06
  • React中使用antd組件的方法

    React中使用antd組件的方法

    antd?是基于?Ant?Design?設(shè)計(jì)體系的?React?UI?組件庫,主要用于研發(fā)企業(yè)級(jí)中后臺(tái)產(chǎn)品,這篇文章主要介紹了React中使用antd組件,需要的朋友可以參考下
    2022-09-09
  • React中使用Redux Toolkit狀態(tài)管理的示例詳解

    React中使用Redux Toolkit狀態(tài)管理的示例詳解

    在現(xiàn)代 React 應(yīng)用程序中,狀態(tài)管理是一個(gè)至關(guān)重要的部分,使用 Redux Toolkit 可以簡化 Redux 的配置和管理,本文將通過三個(gè)文件的示例,詳細(xì)講解如何使用 Redux Toolkit 創(chuàng)建和管理一個(gè)簡單的計(jì)數(shù)器狀態(tài),需要的朋友可以參考下
    2024-11-11
  • React antd tabs切換造成子組件重復(fù)刷新

    React antd tabs切換造成子組件重復(fù)刷新

    這篇文章主要介紹了React antd tabs切換造成子組件重復(fù)刷新,需要的朋友可以參考下
    2021-04-04
  • react腳手架構(gòu)建運(yùn)行時(shí)報(bào)錯(cuò)問題及解決

    react腳手架構(gòu)建運(yùn)行時(shí)報(bào)錯(cuò)問題及解決

    這篇文章主要介紹了react腳手架構(gòu)建運(yùn)行時(shí)報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03

最新評(píng)論

龙口市| 阿克苏市| 横山县| 五寨县| 东明县| 滦南县| 洪雅县| 梅州市| 红安县| 民乐县| 宝鸡市| 彰武县| 冷水江市| 阳春市| 堆龙德庆县| 阿拉善右旗| 浪卡子县| 湟源县| 纳雍县| 康马县| 孟村| 峨山| 舞阳县| 永安市| 巴楚县| 南阳市| 额济纳旗| 边坝县| 马山县| 翁牛特旗| 江北区| 海宁市| 车致| 黄梅县| 岐山县| 三明市| 崇左市| 金塔县| 长宁区| 东兰县| 万山特区|