JS遞歸遍歷查詢是否有權(quán)限示例詳解
前言
最近參與了一個基于 qiankun 構(gòu)建的微前端大型項目,涉及到十幾個子應(yīng)用,基于基座獨立開發(fā)了一個完善的權(quán)限中心模塊。而權(quán)限中心中涉及到了 模塊 > 一級菜單 > N級菜單/按鈕 結(jié)構(gòu)的權(quán)限管理。
這次的需求是在其中一個子應(yīng)用的按鈕級別的權(quán)限管理,在鑒權(quán)階段寫了一個小的方法,用來從權(quán)限樹中查詢是否有某一個按鈕的權(quán)限,從而控制用戶對于按鈕的使用權(quán)限。
需求分析
- 權(quán)限的每一層對應(yīng)的子菜單的鍵不盡相同。
- 在業(yè)務(wù)中,從權(quán)限樹中獲取是否擁有該權(quán)限。
- 按鈕級別的菜單名稱可能重復(fù)。
設(shè)計思路
- 通過對權(quán)限樹的分析有如下結(jié)論:
- 權(quán)限樹的層級是有限的
- 子菜單對應(yīng)的鍵不盡相同,有的是children,有的是functionList,有的是menuList
- 同一層沒有重復(fù)的菜單項
- 設(shè)計一個可以遍歷的數(shù)據(jù)結(jié)構(gòu),對結(jié)構(gòu)進行遍歷查找
- 能找到且數(shù)據(jù)結(jié)構(gòu)一致則返回 true,任意一級沒有找到則返回 false
代碼
因為場景中,需求分析第一條中的原因,不能使用常見的遞歸方法,所以就結(jié)合數(shù)據(jù)創(chuàng)建一個可以使用遞歸解決問題的數(shù)據(jù)結(jié)構(gòu)。
這次使用是使用 do-while 方法進行遞歸 findMap 模板。至于為何需要三個字段也是因為子菜單對應(yīng)的鍵不一樣。當(dāng)然可以改原來的數(shù)據(jù)結(jié)構(gòu),但是改起來比較麻煩,而且影響范圍太廣,所以只能這么做了。
聲明查找模板如下
interface findItem {
findKey: string // 目標(biāo)項的key
findVal: string // 目標(biāo)項的value
childrenKey: string // 子菜單的key
}
// 查找模板
const findMap = [
{findkey: 'name', findVal: "模塊A", childrenKey:'functionList'},
{findkey: 'functionName', findVal: '菜單1', childrenKey:'children'},
{findkey: 'functionName', findVal: '菜單1-1', childrenKey:'children'},
{findkey: 'functionName', findVal: '按鈕1-1-3'}
]
接下來就是遞歸 findItem[]。
很明顯,循環(huán)體中的查找方法其實有很多種,而我選擇了數(shù)組的 filter 方法也是臨時想到的,數(shù)組的方法中有好幾個(例如:some/include)也可以實現(xiàn)循環(huán)體的結(jié)果。
js 版本
/**
* 查詢是否存在 findMap 的結(jié)構(gòu)數(shù)據(jù)
* @param arr getJsonV2 接口返回的權(quán)限列表
* @param findMap findItem[]
* @result boolean
*/
const isAccessInDataByMap = (arr, findMap) => {
let findList = arr // 重置查找范圍
let i= 0 // 初始值
let tempArr = [] //
do {
tempArr = findList.filter(item => item[findMap[i].findkey] === findMap[i].findVal)
if(tempArr.length > 0){
findList = tempArr[0][findMap[i].childrenKey]
i++
}else{
return false
}
} while (i< findMap.length);
if(tempArr.length && i === findMap.length){
return true
}
}
ts 版本
// tool-is-has-access-in-data-by-map.ts
// 聲明接口
export interface findItem {
findKey: string
findVal: string
childrenKey: string
}
/**
* 查詢是否存在 findMap 的結(jié)構(gòu)數(shù)據(jù)
* @param arr getJsonV2 接口返回的權(quán)限列表
* @param findMap findItem[]
* @result boolean
*/
export const isAccessInDataByMap:(data:any, findMap:findItem[]) => boolean | undefined = (data:any, findMap:findItem[]) => {
let findList = data // 重置查找范圍
let i= 0 // 記錄下標(biāo)
let tempArr = []
do {
tempArr = findList.filter((item: { [x: string]: string; }) => item[findMap[i].findKey] === findMap[i].findVal)
if(tempArr.length > 0){
findList = tempArr[0][findMap[i].childrenKey]
i++
}else{
return false
}
} while (i< findMap.length);
if(tempArr.length && i === findMap.length){
return true
}
};
后記
這個方法記下來的原因其實并不是因為這個場景,而是因為一個解決問題的思路。
常見的樹狀結(jié)構(gòu)一般來說都是每一層的數(shù)據(jù)結(jié)構(gòu)都是一樣的,只有最后一層沒有子元素,這樣就可以作為跳出遞歸條件。而這個場景下雖然每一層數(shù)據(jù)結(jié)構(gòu)也幾乎相同,但是每一層用來 核對 的鍵值對卻不一樣。這樣一來就需要有 一把尺子 來查找了。
方法不難,難的是如何總結(jié)為一個通用的解決方案,完成 從 0 到 1 的過程,進而 從 1 到 n。
以上就是JS遞歸遍歷查詢是否有權(quán)限示例詳解的詳細(xì)內(nèi)容,更多關(guān)于JS遞歸遍歷查詢權(quán)限的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序 實現(xiàn)動態(tài)顯示和隱藏某個控件
這篇文章主要介紹了微信小程序 實現(xiàn)動態(tài)顯示和隱藏某個控件的相關(guān)資料,需要的朋友可以參考下2017-04-04
JavaScript編程通過Matlab質(zhì)心算法定位學(xué)習(xí)
這篇文章主要為大家介紹了JavaScript編程中通過Matlab質(zhì)心算法來定位的算法學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10
WindiCSS實現(xiàn)加載windi.config.ts配置文件詳解
這篇文章主要為大家介紹了WindiCSS實現(xiàn)加載windi.config.ts配置文件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02
JSON字符串轉(zhuǎn)換JSONObject和JSONArray的方法
這篇文章主要介紹了JSON字符串轉(zhuǎn)換JSONObject和JSONArray的方法的相關(guān)資料,需要的朋友可以參考下2016-06-06

