如何實現後臺管理系統的權限路由和權限菜單

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"前言"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文是繼 實戰的最後一篇文章, 主要介紹"},{"type":"text","marks":[{"type":"strong"}],"text":"如何實現後臺管理系統的權限路由和權限菜單"},{"type":"text","text":". 希望通過這3篇文章的覆盤和實戰, 可以讓大家開發企業應用的時候更加遊刃有餘."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文主要涉及的技術點如下:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如何使用"},{"type":"text","marks":[{"type":"strong"}],"text":"遞歸算法"},{"type":"text","text":"動態渲染不定層級的菜單"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如何基於權限來控制菜單展現"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"基於"},{"type":"text","marks":[{"type":"strong"}],"text":"nodejs"},{"type":"text","text":"的權限服務設計"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"正文"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"動態菜單和權限路由是後臺管理系統設計中必不可少的環節, 作爲複雜後臺管理系統來說, 導航菜單往往不是簡單的一級菜單, 往往都會有3級,4級菜單, 如下:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d7/d7cc6fe11a7c0593f6a0de42d7163c52.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以我們首要解決的問題就是面對"},{"type":"text","marks":[{"type":"strong"}],"text":"未知層級菜單"},{"type":"text","text":"時的前端解決方案. 其次就是面對不同角色,需要展示不同的權限菜單, 我們如何解決這兩個問題, 是實現權限菜單的第一步,接下來筆者就會帶大家一起實現."}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"使用遞歸算法動態渲染不定層級的菜單"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先我們來解決第一個問題, 實現渲染不定層級的菜單. 我們目前常用的菜單schema如下:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"const menuData = [\n {\n key: '/manage',\n path: '/manage',\n text: 'dooring工作臺',\n },\n {\n key: '/manage/anazly',\n path: '/manage/anazly',\n text: '數據大盤',\n },\n {\n key: '/manage/h5',\n text: 'H5服務中心',\n sub: [\n {\n key: '/manage/h5/config',\n path: '/manage/h5/config',\n text: 'H5頁面管理',\n },\n {\n key: '/manage/h5/tpl',\n path: '/manage/h5/tpl',\n text: '模板庫',\n }\n ]\n },\n {\n key: '/manage/order',\n path: '/manage/order',\n text: '訂單管理',\n }\n]\n複製代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們可以通過實現一個js算法來遍歷這個數據生成動態菜單, 比如for, 遞歸等, 筆者這裏採用遞歸來實現, 關於菜單組件的選擇, 我們可以使用"},{"type":"text","marks":[{"type":"strong"}],"text":"antd"},{"type":"text","text":"的"},{"type":"text","marks":[{"type":"strong"}],"text":"Menu"},{"type":"text","text":", 也可以使用"},{"type":"text","marks":[{"type":"strong"}],"text":"element UI"},{"type":"text","text":", "},{"type":"text","marks":[{"type":"strong"}],"text":"iView"},{"type":"text","text":"等, 原理基本一致, 這裏筆者直接寫出我的"},{"type":"text","marks":[{"type":"strong"}],"text":"javascript"},{"type":"text","text":"遞歸版本:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"const { SubMenu } = Menu;\nconst createMenu = (menu = []) => {\n return menu.map(item => {\n if(item.sub) {\n return \n { createMenu(item.sub) }\n \n }else {\n return \n { item.text }\n \n }\n })\n }\n複製代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過以上方式我們就可以渲染出任何層級的菜單了, 在"},{"type":"text","marks":[{"type":"strong"}],"text":"H5-Dooring"},{"type":"text","text":"後臺中效果如下:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/97/97dc232a2562c7655a2d444bb852f292.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果沒有權限需求, 大家可以直接用以上方案實現任何動態層級菜單. 接下來我們來實現具有權限功能的動態菜單."}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"基於權限來控制菜單展現"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在上面的實現中我們已經實現了動態層級菜單, 對於有權限管理功能的系統, 我們需要對不同用戶展現不同菜單, 比如"},{"type":"text","marks":[{"type":"strong"}],"text":"超級管理員"},{"type":"text","text":", "},{"type":"text","marks":[{"type":"strong"}],"text":"普通管理員"},{"type":"text","text":", 或者更細的劃分, 我們需要在遍歷菜單的時候去動態根據權限過濾, 接下來我們看一個例子:超級管理員登錄的菜單界面:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/88/88c424e12378480440d2265599c75826.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"普通管理員登錄的菜單界面:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/69/6913be4a3905a94b2bd86fda0dbf7e9e.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先要想實現權限菜單, 我們需要修改菜單schema結構, 添加權限字段,如下:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"const menuData = [\n {\n key: '/manage',\n path: '/manage',\n text: 'dooring工作臺'\n },\n {\n key: '/manage/anazly',\n path: '/manage/anazly',\n text: '數據大盤',\n },\n {\n key: '/manage/auth',\n path: '/manage/auth',\n text: '會員管理',\n auth: true,\n },\n {\n key: '/manage/h5',\n text: 'H5服務中心',\n sub: [\n {\n key: '/manage/h5/config',\n path: '/manage/h5/config',\n text: 'H5頁面管理',\n },\n {\n key: '/manage/h5/tpl',\n path: '/manage/h5/tpl',\n text: '模板庫',\n auth: true,\n }\n ]\n }\n]\n複製代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上圖可知我們添加了"},{"type":"text","marks":[{"type":"strong"}],"text":"auth"},{"type":"text","text":"字段作爲權限標示, 這裏我們主要用"},{"type":"text","marks":[{"type":"strong"}],"text":"true"},{"type":"text","text":"和"},{"type":"text","marks":[{"type":"strong"}],"text":"false"},{"type":"text","text":"表示, 因爲這裏只有2中角色, 如果有多種權限, 我們可以用特殊字符串或者數字表示, 這塊只需要和後端約定好即可. 具體實現如下:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"const createMenu = (menu = []) => {\n return menu.map(item => {\n if(item.sub) {\n return \n { createMenu(item.sub) }\n \n }else {\n if((rp === 'super' && item.auth) || !item.auth) {\n return \n { item.text }\n \n }else {\n return null\n }\n }\n })\n }\n複製代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上就實現了動態不限層級的"},{"type":"text","marks":[{"type":"strong"}],"text":"權限菜單"},{"type":"text","text":". 大家可以直接食用哈~"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"基於nodejs的權限服務設計"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上實現主要是前端層面的設計方案, 我們都知道前端的安全措施永遠是不可靠的, 所以我們爲了保證系統的安全性, 一般我們會把菜單數據存到後端, 通過接口動態請求權限菜單. 這塊我們可以提前和後端做好約定, 讓後端根據不同用戶返回不同的權限菜單"},{"type":"text","marks":[{"type":"strong"}],"text":"schema"},{"type":"text","text":"即可. 由於方案比較簡單, 這裏筆者就不一一介紹了. 感興趣可以在參考"},{"type":"text","marks":[{"type":"strong"}],"text":"H5-Dooring"},{"type":"text","text":"的實現."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"所以, 今天你又博學了嗎?"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"最後"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上教程筆者已經集成到"},{"type":"link","attrs":{"href":"https://github.com/MrXujiang/h5-Dooring","title":null},"content":[{"type":"text","text":"H5-Dooring"}]},{"type":"text","text":"中,對於一些更復雜的交互功能,通過合理的設計也是可以實現的,大家可以自行探索研究。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"github地址:"},{"type":"link","attrs":{"href":"https://github.com/MrXujiang/h5-Dooring","title":null},"content":[{"type":"text","text":"H5編輯器H5-Dooring"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"開源投票入口:"},{"type":"link","attrs":{"href":"https://www.oschina.net/p/h5-dooring","title":null},"content":[{"type":"text","text":"爲H5-Dooring投票"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果想學習更多H5遊戲, "},{"type":"text","marks":[{"type":"strong"}],"text":"webpack"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"node"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"gulp"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"css3"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"javascript"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"nodeJS"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"canvas"},{"type":"text","text":"數據可視化等前端知識和實戰,歡迎在《趣談前端》一起學習討論,共同探索前端的邊界。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章