【Vue框架】菜單欄權限的使用與顯示

前言

在 【Vue框架】Vue路由配置 中的getters.js里,可以看到有一個應用程序的狀態(變量)叫 permission_routes,這個就是管理前端菜單欄的狀態。具體代碼的介紹,都以注釋的形式來說明。

1、modules\permission.js

1.1 代碼

import { asyncRoutes, constantRoutes } from '@/router'/*** Use meta.role to determine if the current user has permission* @param roles 用戶角色* @param route 路由信息*/
function hasPermission(roles, route) {// 判斷route是否存在meta和meta.rolesif (route.meta && route.meta.roles) {// 判斷當前傳入的角色,是否存在路由的route中return roles.some(role => route.meta.roles.includes(role))} else {return true}
}/*** Filter asynchronous routing tables by recursion* 通過 遞歸 篩選異步路由表* 【將 基礎路由(不含角色權限)和 符合用戶權限的動態路由(需要角色權限)全部存入res】* @param routes asyncRoutes【去看router\index.js中asyncRoutes】* @param roles*/
export function filterAsyncRoutes(routes, roles) {const res = []// routes是在router\index.js定義的路由數組routes.forEach(route => {const tmp = { ...route } // 數組中遍歷獲取其中路由對象if (hasPermission(roles, tmp)) { // 判斷當前路由是否存在角色if (tmp.children) { // 判斷當前路由是否存在二級路由tmp.children = filterAsyncRoutes(tmp.children, roles)}res.push(tmp)}})return res
}// 定義的狀態
const state = {routes: [],addRoutes: []
}// 用于存儲一系列 改變 應用狀態的方法
const mutations = {SET_ROUTES: (state, routes) => {state.addRoutes = routesstate.routes = constantRoutes.concat(routes) // 用戶角色的動態路由加入到基礎路由中}
}// 用于存儲一系列 觸發改變 應用狀態的方法
const actions = {generateRoutes({ commit }, roles) {return new Promise(resolve => {let accessedRoutesif (roles.includes('admin')) { // 如果roles數組中包含'admin'accessedRoutes = asyncRoutes || [] // 動態路由全部可以訪問,如果asyncRoutes為`undefined`或`null`,則取[]} else {accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) // 遞歸出符合條件的路由}commit('SET_ROUTES', accessedRoutes)resolve(accessedRoutes)})}
}
// 默認導出一個對象,包含了模塊的相關配置
export default {// 設置模塊的命名空間為 `true`,這意味著該模塊中的狀態、mutations、getters、actions將被封裝在命名空間中,以避免和其他模塊的沖突namespaced: true,// 模塊的狀態state,// 模塊的變化方法mutations,// 模塊的行為方法(調用action,觸發mutations,改變state)actions
}

該文件除了定義的routes路由狀態和addRoutes動態添加的路由(后續用到的時候在提),主要在actions中定義了生成路由的行為方法generateRoutes,根據roles角色和內置傳入的{ commit }context.commit)獲取router\index.js中定義的一系列路由,簡單說,就是在前端頁面上被訪問的路徑

補充防忘記:

  1. new Promise()以及其參數
  2. 【Vue框架】Vue路由配置 看看路由
  3. 【Vue框架】Vuex狀態管理

1.2 想法:

modules\permission.js中,根據generateRoutes提前寫好的邏輯來判斷查回用戶的權限是否符合,這樣不利于添加新角色的改動。
應該都得從數據庫中查詢,得到庫中的角色和每個動態路由。(個人猜想,后續在嘗試)

2、layout\components\Sidebar

2.1 index.vue

遍歷展示整體的菜單欄。

<template><div :class="{'has-logo':showLogo}"><logo v-if="showLogo" :collapse="isCollapse" /><el-scrollbar wrap-class="scrollbar-wrapper"><el-menu:default-active="activeMenu":collapse="isCollapse":background-color="variables.menuBg":text-color="variables.menuText":unique-opened="false":active-text-color="variables.menuActiveText":collapse-transition="false"mode="vertical"><sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" /></el-menu></el-scrollbar></div>
</template><script>
import { mapGetters } from 'vuex' // 從`vuex`庫中導入`mapGetters`函數,用于將getter映射到該組件的計算屬性中
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/styles/variables.scss'export default {// 在該組件中注冊了`SidebarItem`和`Logo`兩個組件,以便在模板中使用它們components: { SidebarItem, Logo },// `computed`計算屬性中,可以定義一些依賴于其他數據的屬性。這些屬性的值會根據其依賴的數據動態計算得出,并在依賴數據發生變化時自動更新。// `computed`計算屬性的定義方式可以是一個對象,對象的每個屬性都是一個計算屬性的定義// `...mapGetters([...])`將`mapGetters`返回的映射對象展開并添加到該組件的計算屬性中,這樣可以直接訪問映射的getter// mapGetters([...])里的數組中包含想要映射的getter方法的名稱computed: {...mapGetters(['permission_routes','sidebar']),// 根據當前路由對象的元信息(`meta`)中的`activeMenu`屬性來確定活動的菜單項。// 如果未設置`activeMenu`屬性,則返回當前路徑(`path`)activeMenu() {const route = this.$route // `this.$route`是在Vue中訪問當前路由的對象(全局屬性,只讀,不能直接更改路由信息)const { meta, path } = route// if set path, the sidebar will highlight the path you setif (meta.activeMenu) {return meta.activeMenu // 側邊欄將高亮顯示設置的路徑}return path // 如果未設置`activeMenu`屬性,則返回當前路由的路徑。側邊欄將根據當前路徑高亮顯示相應的菜單項},showLogo() {return this.$store.state.settings.sidebarLogo},variables() {return variables},isCollapse() {// 如果`opened`屬性為`true`,則`isCollapse`為`false`,表示側邊欄未折疊;// 如果`opened`屬性為`false`,則`isCollapse`為`true`,表示側邊欄已折疊return !this.sidebar.opened}}
}
</script>

2.2 SidebarItem.vue

具體遍歷顯示每一個具體的菜單項。

<template><div v-if="!item.hidden" class="menu-wrapper"><!-- 這的item就是route,onlyOneChild就是當前route下的子菜單 --><!-- 1判斷route下是否為01個子菜單 && 2(!當前route下的子菜單是還存在子菜單||子菜單不存在時) &&  3--><!-- 這里的template:當前route下只有1個或0個子菜單,且唯一子菜單下不存在下級菜單時,執行這段代碼效果:菜單欄中,該route為一級菜單,不顯示其子菜單--><template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"><!-- 其子菜單中存在meta --><app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"><el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"><item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" /></el-menu-item></app-link></template><!--  存在多級子菜單的時候  --><el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body><!-- 這里的插槽名為title;作用和上面一樣,主要是顯示一級菜單,但這里沒用app-link讓該菜單具有跳轉功能 --><template slot="title"><item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /></template><!-- 具體的菜單項,遍歷各個子菜單 --><sidebar-itemv-for="child in item.children":key="child.path":is-nest="true":item="child":base-path="resolvePath(child.path)"class="nest-menu"/></el-submenu></div>
</template><script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'export default {name: 'SidebarItem',components: { Item, AppLink },// 通過 `mixins` 可以將一些常用的選項(如 `data`、`methods`、`created` 等)或復雜邏輯封裝成可復用的模塊,并在多個組件中混入使用mixins: [FixiOSBug],// 用于定義組件的屬性。可以是數組、對象或具體的屬性定義。通過 props 可以接收組件外部傳入的數據,并在組件內部使用props: {// route objectitem: {type: Object,required: true},isNest: {type: Boolean,default: false},basePath: {type: String,default: ''}},data() {// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237// TODO: refactor with render function// 當前route的子菜單this.onlyOneChild = nullreturn {}},methods: {hasOneShowingChild(children = [], parent) {const showingChildren = children.filter(item => {if (item.hidden) {return false} else {// Temp set(will be used if only has one showing child)this.onlyOneChild = itemreturn true}})// 只存在一個子菜單// When there is only one child router, the child router is displayed by defaultif (showingChildren.length === 1) {return true}// 不存在菜單// Show parent if there are no child router to displayif (showingChildren.length === 0) {// 如果沒有子菜單顯示,將父級菜單的一些屬性復制到`onlyOneChild`對象中,同時設置`onlyOneChild`的`path`為空字符串,// 并設置`noShowingChildren`屬性為`true`,表示沒有子菜單顯示。最后返回`true`。this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }return true}// 子菜單存在多個的時候return false},resolvePath(routePath) {// `isExternal(routePath)`函數判斷`routePath`是否為外部鏈接,如果是外部鏈接,則直接返回`routePath`,不做處理// 當只有唯一子菜單時,`routePath`是子菜單路徑if (isExternal(routePath)) {return routePath}// 當只有唯一子菜單時,`basePath`是父級菜單的路徑if (isExternal(this.basePath)) {return this.basePath}// `path.resolve()`函數將`this.basePath`和`routePath`拼接成一個完整的路徑,并返回該路徑// 返回 `/父級菜單的路徑/子菜單路徑`return path.resolve(this.basePath, routePath)}}
}
</script>

2.3 Link.vue

<template><!-- eslint-disable vue/require-component-is --><component v-bind="linkProps(to)"><slot /></component>
</template><script>
import { isExternal } from '@/utils/validate'export default {props: {to: {type: String,required: true}},methods: {linkProps(url) {if (isExternal(url)) {return {is: 'a', // 標簽名href: url, // 鏈接target: '_blank', // 用于指定鏈接在哪個窗口或框架中打開,`_blank`在新的標簽頁中打開鏈接rel: 'noopener' // 用于指定鏈接與當前頁面之間的關系,當使用`target="_blank"`時,防止新打開的窗口通過`window.opener`屬性訪問到當前頁面的信息,提高安全性。}}return {is: 'router-link', // 標簽名to: url}}}
}
</script>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/36721.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36721.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36721.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SpringBoot 將項目打包成 jar 包

SpringBoot 將項目打包成 jar 包 一、項目打包成 jar 包 首先在 pom.xml 文件中導入 Springboot 的 maven 依賴 <!-- 將應用打包成一個可以執行的 jar 包 --> <build><plugins><plugin><groupId>org.springframework.boot</groupId><…

學習筆記整理-面向對象-02-認識函數的上下文

一、認識函數的上下文 什么是上下文 垃圾分類&#xff0c;這是非常好的習慣&#xff0c;值得表揚隨手關燈&#xff0c;這是非常好的習慣&#xff0c;值得表揚遛狗栓繩&#xff0c;這是非常好的習慣&#xff0c;值得表揚課后復習&#xff0c;這是非常好的習慣&#xff0c;值得…

【數據結構】單鏈表OJ題(二)

&#x1f525;博客主頁&#xff1a;小王又困了 &#x1f4da;系列專欄&#xff1a;數據結構 &#x1f31f;人之為學&#xff0c;不日近則日退 ??感謝大家點贊&#x1f44d;收藏?評論?? 目錄 一、鏈表分割 &#x1f4a1;方法一&#xff1a; 二、鏈表的回文 &#x…

hosts文件中被添加 windows10.microdone.cn

在網上搜了一圈逗說是之前下過征信中心的安全控件,是微通新成網絡科技有限公司這家公司提供的,也是http://microdone.cn的運營商。后邊只要使用代理,就會跳出來,所以常規處理操作就是去把瀏覽器上的安全控件卸載了。 參考 解決 windows10 的 代理頻繁被自動篡改為windows10.mi…

利用python實現激光雷達LAS數據濾波的7種方式,使用laspy讀寫

激光雷達&#xff08;LiDAR&#xff09;數據在實際應用中可能受到噪聲和不完美的測量影響&#xff0c;因此數據去噪和濾波方法變得至關重要&#xff0c;以提高數據質量和準確性。以下是一些常用的激光雷達數據去噪與濾波方法。 原始數據如下&#xff1a; 1. 移動平均濾波&…

kubernetes中PV和PVC

目錄 一、PV、PVC簡介 二、PV、PVC關系 三、創建靜態PV 1.配置nfs存儲 2.定義PV 3.定義PVC 4.測試訪問 四、 搭建 StorageClass nfs-client-provisioner &#xff0c;實現 NFS 的動態 PV 創建 1. 配置nfs服務 2.創建 Service Account 3.使用 Deployment 來創建 NFS P…

Figma中文社區來啦,云端協作設計你準備好了嗎?

Figma是改變產品設計協作方式的重要工具,但由于沒有中文社區,對國內設計師的約束較大。而擁有全中文UI 界面、功能齊全的即時設計資源廣場,恰好彌補了Figma的這一短板,它也將取代Figma成為設計師新寵。 1、UI組件集 Figma中文社區替代即時設計資源廣場,擁有海量豐富的UI設計組…

【BEV Review】論文 Delving into the Devils of Bird’s-eye-view 2022-9 筆記

背景 一般來說&#xff0c;自動駕駛車輛的視覺傳感器&#xff08;比如攝像頭&#xff09;安裝在車身上方或者車內后視鏡上。無論哪個位置&#xff0c;攝像頭所得到的都是真實世界在透視視圖&#xff08;Perspective View&#xff09;下的投影&#xff08;世界坐標系到圖像坐標系…

ssm柚子云電子商城java圖書購物電子商務管理jsp源代碼

本項目為前幾天收費幫學妹做的一個項目&#xff0c;Java EE JSP項目&#xff0c;在工作環境中基本使用不到&#xff0c;但是很多學校把這個當作編程入門的項目來做&#xff0c;故分享出本項目供初學者參考。 一、項目描述 ssm柚子云電子商城 系統有2權限&#xff1a;前臺、后…

SpringBoot筆記:SpringBoot 集成 Dataway 多數據源配置(二)

文章目錄 前言核心代碼和配置yml 配置注入多數據源常用Spi實現swagger 配置自定義 Udf指定數據源進行查詢 前言 之前簡單介紹了一下 Dataway 使用&#xff0c;本文繼續介紹一下它的多數據源配置和使用。 核心代碼和配置 yml 配置 # springboot多環境配置 #端口&#xff0c;…

JavaScript應用:五子棋游戲實戰開發

&#x1f3c6;作者簡介&#xff0c;黑夜開發者&#xff0c;全棧領域新星創作者?&#xff0c;CSDN博客專家&#xff0c;阿里云社區專家博主&#xff0c;2023年6月csdn上海賽道top4。 &#x1f3c6;數年電商行業從業經驗&#xff0c;歷任核心研發工程師&#xff0c;項目技術負責…

面試熱題(螺旋矩陣)

給你一個 m 行 n 列的矩陣 matrix &#xff0c;請按照 順時針螺旋順序 &#xff0c;返回矩陣中的所有元素 一看到這個大家有沒有想到 就是一個螺旋形狀&#xff0c;那這道題我們應該怎么解決&#xff1f; 我們先來仔細的看&#xff0c;它這種螺旋形狀的遍歷是先【右-下-左-上】…

Docker中Tomcat部署步驟

第一次訪問沒有東西。

為什么我不推薦任何人用C語言作為編程啟蒙第一課?

前言 寫了20多年的代碼&#xff0c;之前做過阿里的高級架構師&#xff0c;在技術這條路上跌跌撞撞了很多&#xff0c;我今天分享一些我個人的自學方法給各位。為什么我會說&#xff1a;不推薦任何人用C語言作為編程啟蒙第一課&#xff1f; 這里有很多同學要站出來說了&#x…

實現CP指令

一、文件的打開創建 #include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char *pathname, int flags); flags: O_RDONLY 只讀 O_WRONLY 只寫 O_RDWR 可讀可寫 int open(const char *pathname, int flags, mode_t mode); 如果 …

VsCode美化 - VsCode自定義 - VsCode自定義背景圖

VsCode美化 - VsCode自定義 - VsCode自定義背景圖&#xff1a;添加二次元老婆圖到VsCode 前言 作為一個二刺螈&#xff0c;VsCode用久了&#xff0c;總覺得少了些什么。是啊&#xff0c;高效的代碼生產工具中怎么能沒有老婆呢&#xff1f; 那就安裝一個VsCode插件把老婆添加…

章節7:Burp Intruder模塊

章節7&#xff1a;Burp Intruder模塊 參考資料 https://portswigger.net/burp/documentation/desktop/tools/intruder 01 Intruder模塊作用與原理 原理 http://xxx.xx.com/bbs/index.php?namewuyanzu&mottogo 對請求參數進行修改&#xff0c;分析響應內容&#xff0…

Linux 內核第一版 (v0.01) 開源代碼解讀

探索Linux v0.01的內部結構&#xff0c;Linux內核經常被認為是一個龐大的開源軟件。在撰寫本文時&#xff0c;最新版本是v6.5-rc5&#xff0c;包含36M行代碼。不用說&#xff0c;Linux是幾十年來許多貢獻者辛勤工作的成果。 Linux 內核首個開源版本 (v0.01) 的體積非常小&…

四、Dubbo擴展點加載機制

四、Dubbo擴展點加載機制 4.1 加載機制概述 Dubbo良好的擴展性與框架中針對不同場景使用合適設計模式、加載機制密不可分 Dubbo幾乎所有功能組件都是基于擴展機制&#xff08;SPI&#xff09;實現的 Dubbo SPI 沒有直接使用 Java SPI&#xff0c;在它思想上進行改進&#xff…

競賽項目 深度學習的視頻多目標跟蹤實現

文章目錄 1 前言2 先上成果3 多目標跟蹤的兩種方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟蹤過程4.1 存在的問題4.2 基于軌跡預測的跟蹤方式 5 訓練代碼6 最后 1 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 基于深度學習的視頻多目標跟蹤實現 …