ant design pro 程式碼學習(三) ----- 選單資料分析
1、getSelectedMenuKeys 獲取選中的選單的key
getSelectedMenuKeys = () => {
const {location: {pathname}} = this.props;
return getMeunMatchKeys(this.flatMenuKeys, urlToList(pathname));
};
getSelectedMenuKeys中涉及到getMeunMatchKeys()、this.flatMenuKeys、urlToList(),下邊分別對其進行分析。
this.flatMenuKeys = getFlatMenuKeys(props.menuData);
.....
export const getFlatMenuKeys = menu =>
menu.reduce((keys, item) => {
keys.push(item.path);
if (item.children) {
return keys.concat(getFlatMenuKeys(item.children));
}
return keys;
}, []);
getFlatMenuKeys通過對props.menuData資料遞迴呼叫,返回props.menuData中所有層級資料的path值(Array型別),其中path為完整的路徑值(getMenuData()已處理過)
export function urlToList(url) {
//filter(i => i) 去除空
const urllist = url.split('/').filter(i => i);
return urllist.map((urlItem, index) => {
return `/${urllist.slice(0, index + 1).join('/')}`;
});
}
將pathname傳入到urlToList方法中,urlToList首先對url用’/’分割,filter方法對空值進行處理(分割後第一個元素為空)。返回一級路徑、二級路徑…依次類推。例如當前pathname為/A/B時,則返回[‘/A’,’/A/B’]
export const getMeunMatchKeys = (flatMenuKeys, paths) =>
paths.reduce((matchKeys, path) => (
matchKeys.concat(
flatMenuKeys.filter(item => pathToRegexp(item).test(path))
)), []);
getMeunMatchKeys對flatMenuKeys、paths做雙重迴圈,其中pathToRegexp會對/path/:id等資料做處理,會匹配/path路徑。返回值為,flatMenuKeys中包含的paths元素(返回型別Array)。
綜上所述,getFlatMenuKeys返回當前路由的pathname對應在flatMenuKeys中匹配項。例如當前pathname=’/dashboard/analysis’(有效路由),則返回[‘/dashboard’,’/dashboard/analysis’];當前pathname=’/aaa’(無效路由),則返回[],因為flatMenuKeys找不到匹配項。
2、handleOpenChange 切換選單時,更改選中的選單key
isMainMenu = key => {
return this.menus.some(item => key && (item.key === key || item.path === key));
};
handleOpenChange = openKeys => {
const lastOpenKey = openKeys[openKeys.length - 1];
const moreThanOne = openKeys.filter(openKey => this.isMainMenu(openKey)).length > 1;
this.setState({
openKeys: moreThanOne ? [lastOpenKey] : [...openKeys],
});
};
......
//Menu元件中onOpenChange事件
onOpenChange={this.handleOpenChange}
isMainMenu用來檢測當前路徑是否為一級選單路徑。
由ant design中的Menu元件可知,onOpenChange事件的回撥方法中,傳入引數openKeys為當前多級路徑、將被開啟的路徑的集合。
如果當前路徑、即將開啟的路徑是一級選單間切換,則moreThanOne必為true,例如當前’/dashboard/analysis’,即將開啟’/list’,此時openKeys為[‘/dashboard’,’/dashboard/analysis’,’/list’],則openKeys為即將開啟的頁面的路由,即/list’;
如果是當前選單的子選單開啟,則moreThanOne為false,例如當前開啟的選單時’/list’(列表項),即將開啟’/list/search’(搜尋列表),則openKeys為[“/list”, “/list/search”],此時Menu元件會開啟:列表-搜尋列表;
如果,點選當前開啟的選單,則此時即為關閉選單,openKeys為[]。
*注:結合getSelectedMenuKeys、handleOpenChange。對selectedKeys做了如下處理:如果根據當前路由資訊找不到匹配的選單項,則當前選中的選單項為解決要開啟的選單項。*
let selectedKeys = this.getSelectedMenuKeys();
if (!selectedKeys.length) {
selectedKeys = [openKeys[openKeys.length - 1]];
}
3、getNavMenuItems 、getSubMenuOrItem獲取選單項入口方法
getNavMenuItems獲取存在選單名稱(name)、且可見的選單(!item.hideInMenu)。其中getSubMenuOrItem根據當前的是否存在子選單返回或者
getNavMenuItems = menusData => {
if (!menusData) {
return [];
}
return menusData
.filter(item => item.name && !item.hideInMenu)
.map(item => {
// make dom
const ItemDom = this.getSubMenuOrItem(item);
return this.checkPermissionItem(item.authority, ItemDom);
})
.filter(item => item);
};
getSubMenuOrItem = item => {
if (item.children && item.children.some(child => child.name)) {
const childrenItems = this.getNavMenuItems(item.children);
if (childrenItems && childrenItems.length > 0) {
return (
<SubMenu
title={
item.icon ? (
<span>
{getIcon(item.icon)}
<span>{item.name}</span>
</span>
) : (
item.name
)
}
key={item.path}
>
{childrenItems}
</SubMenu>
);
}
return null;
} else {
return <Menu.Item key={item.path}>{this.getMenuItemPath(item)}</Menu.Item>;
}
};
第一次呼叫getSubMenuOrItem方法,
<Menu>
......
{this.getNavMenuItems(this.menus)}
</Menu>
有如下邏輯,遍及選單資料(一級選單):
1. 如果當前選單資料(item),不存在子選單或者子選單中不存在name屬性時,則判斷為當前選單項沒有子選單,返回Menu.Item;此時代表一級選單沒有子選單,則返回的Menu.Item直接作為
- 如果當前選單資料存在子選單,則對子選單呼叫getNavMenuItems方法,此處存在遞迴呼叫getSubMenuOrItem。繼續執行1、2。當前子選單如果沒有下一級子選單,則返回SubMenu - Menu.Item - SubMenu,如果存在繼續遞迴呼叫。此時一級選單已經確定含有子選單,所以遞迴的結果是作為SubMenu的子元素,當然SubMenu中也有可能包含SubMenu。
4、checkPermissionItem 獲取當前選單的許可權
- 方法使用:
const ItemDom = this.getSubMenuOrItem(item);
return this.checkPermissionItem(item.authority, ItemDom);
- 方法引用
checkPermissionItem = (authority, ItemDom) => {
if (this.props.Authorized && this.props.Authorized.check) {
const {check} = this.props.Authorized;
return check(authority, ItemDom);
}
return ItemDom;
};
由getSubMenuOrItem返回的是SubMenu或者Menu.Item元件,checkPermissionItem方法中的Authorized屬性是元件,由ant design pro 程式碼學習(一) —– 路由分析分析可知,this.props.Authorized.check() 接受三個引數:1、元件的許可權值;2、鑑權通過返回的元件;3、鑑權不通過返回的元件。方法內部會根據當前許可權值authority與currentAuthority對比,決定返回值。
由menuData中的資料可知,當前選單資料中,除了賬戶(user)的authority為’guest’,其他均為undefined。而當前的許可權值currentAuthority是根據呼叫介面’/api/login/account’來確定的(具體在後續登入部分在分析)登入後不為’guest’(具體根據賬號型別為admin或者user)。
check()中當傳入的authority為undefined時,則直接認為是鑑權通過。由於賬戶(user)相關的許可權為guest,不等於’admin’,此時返回undefined(因為鑑權未通過的元件引數未傳入)。getNavMenuItems()方法中通過Array.filter過濾掉undefined、null、‘’ 等元素。否則的話根據react官方文件api可知,在jsx中undefined會被渲染為空
,會生成無效空元素。false,null,undefined,和 true 都是有效的的 children(子元素) 。但是並不會被渲染。 —– react文件-深入 JSX
5、getMenuItemPath 生成選單項
根據選單資料中的path屬性,判斷是否含有https,如果有,則認為是連結,生成a標籤,如果沒有則認為系統內部頁面,則生成Link標籤。getIcon用於生成選單圖示 。
getMenuItemPath = item => {
const itemPath = this.conversionPath(item.path);
const icon = getIcon(item.icon);
const {target, name} = item;
// Is it a http link
if (/^https?:\/\//.test(itemPath)) {
return (
<a href={itemPath} target={target}>
{icon}
<span>{name}</span>
</a>
);
}
return (
<Link
to={itemPath}
target={target}
replace={itemPath === this.props.location.pathname}
onClick={
this.props.isMobile
? () => {
this.props.onCollapse(true);
}
: undefined
}
>
{icon}
<span>{name}</span>
</Link>
);
};
6、選單資料流程圖
相關推薦
ant design pro 程式碼學習(三) ----- 選單資料分析
1、getSelectedMenuKeys 獲取選中的選單的key getSelectedMenuKeys = () => { const {location: {pathname}} = this.props; return g
ant design pro 程式碼學習(二) ----- 路由資料分析
本章節包含路由資訊(common/router)、側邊欄選單資訊(common/menu)、基本路由(一級路由)UserLayout元件,BasicLayout元件、以及側邊欄SiderMenu元件中對資料的處理。主要涉及到以下幾個方法,分別逐個分析其功能。
ant design pro 程式碼學習(六) ----- 知識點總結2
1 、connect 多個model 以下為redux的API中對connect方法的定義: connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
【 專欄 】- ant design pro程式碼學習成果分享
ant design pro程式碼學習成果分享 專注web前端開發。對ant design pro的程式碼進行分析,包含路由、選單、元件封裝、資料mock、相關知識點的總結。後續還會繼續更新,希望我的點滴努力能給帶來一些技術提升。
2.Ant Design Pro的第一個選單
準備 正式開發前需要準備一個IDE,如果是用純記事本的大神請忽略 可以選Sublime和VsCode等,找個自己用過的順手的 反正我都沒用過,跟隨我軟的指令碼我就選VsCode把 在VSCode裡新增一個工程,選定上一章克隆下來的工程資料夾目錄 然後再儲存下工程檔案
Ant Design Pro使用技巧之mock資料地址改為伺服器地址
Ant Design Pro本身提供了較為強大的mock資料的功能。 然而,當如果是單人開發模式或者後臺已經開發完成的情況下,我們更希望在前端開發除錯過程中直接訪問後端服務的介面。 本文主要講述該技巧,即如何將mock資料地址改為伺服器地址 .roadhogrc.mock.js .r
ant design pro的採坑之旅 (動態建立選單、訪問mock資料、富文字編輯器)
最近公司做一個後臺管理系統,猶豫半天還是想用ant design,後來發現他們有現成的腳手架 ant design pro ( github地址 ),果斷拉程式碼下來執行起來。 一:ant design pro 專案目錄結構和流程 整體目錄大概長這個樣子
react+ant design pro 2.0+dva 後臺管理系統,學習筆記
1.如果你熟悉 HTML,那麼 JSX 對於你來說是沒有任何壓力的,因為 HTML 中的所有標籤,在 JSX 中都是支援的,基本上沒有學習成本,只有如下幾點略微的不同: class 屬性變為 className tabindex 屬性變為 tabIndex
ant design pro 新增一級選單和子選單
1.新建個檔案,我這個是複製其它自帶的檔案(list資料夾的TableList.js) 2.然後找到這個檔案 去配router 3.也是copy其它的,就是改一下名字和路徑檔案就好了
Ant Design Pro學習小結
在models的effects中直接用setTimeout函式會報錯,例如以下錯誤寫法: effects: { *update({ payload }, { call, put }) { const response = yield call(update, payload);
ant design pro 配置動態選單、許可權
import React, { Suspense } from 'react'; import { Layout } from 'antd'; import DocumentTitle from 'react-document-title'; import isEqual from 'lodash/isEq
Ant Design Pro學習手記
2.npm install出現問題:npm ERR! network connect ETIMEDOUT。 解決方法:npm install後再使用npm install no-proxy,此後專案可以正常啟動3.關於mock相關問題:.roadhogrc.mock.j
Ant Design Pro 選單icon修改或新增
//自己新增頁面 path: '/qrdata', name: 'qrdata', icon: 'qrcode', //原來的form頁面 path: '/form', icon: 'form
ant-design-pro 動態選單-路由詳解
開發十年,就只剩下這套架構體系了! >>>
Ant Design Pro V5 從伺服器請求選單(typescript版)
## 【前言】 > 找了很多Admin模板,最後還是看中了AntDesignPro(下文簡寫antd pro)這個阿里巴巴開源的Admin框架,長這樣(還行吧,目前挺主流的): 官網地址:[https://pro.ant.design/index-cn](https://pro.ant.design/
004-ant design pro安裝、目錄結構、項目加載啟動
assets ocs win 領域 org 參考 des 布局 class 一、概述 1.1、腳手架概念 編程領域中的“腳手架(Scaffolding)”指的是能夠快速搭建項目“骨架”的一類工具。例如大多數的React
002-ant design pro 布局
篩選 html imp 我們 mas app 路由 http span 一、概述 參看地址:https://pro.ant.design/docs/layout-cn 其實在上述地址ant-design上已經有詳細介紹,本文知識簡述概要。 頁面整體布局是一
003-ant design pro 路由和菜單
部分 doc angle line board 面包屑 腳手架 封裝 ebp 一、概述 參看地址:https://pro.ant.design/docs/router-and-nav-cn 二、原文摘要 路由和菜單是組織起一個應用的關鍵骨架,我們的腳手架提供了
006-ant design pro 樣式
module text patch 導致 multipl 應該 back wid round 一、概述 參看地址:https://pro.ant.design/docs/style-cn 基礎的 CSS 知識或查閱屬性,可以參考 MDN文檔。 二、詳細介紹
010-ant design pro advanced 圖表
mage water 分享 rtc 分享圖片 cit nod 繪制 wave 一、概述 原文地址:https://pro.ant.design/docs/graph-cn Ant Design Pro 提供了由設計師精心設計抽象的圖表類型,是在 BizCharts 圖表