目錄
#登入狀態保存" >#登入狀態保存
登入成功保存資料" >登入成功保存資料
store" >store
元件動態載入" >元件動態載入
核心思路" >核心思路
資料請求時機" >資料請求時機
路由導航守衛" >路由導航守衛
菜单渲染" >菜单渲染
首頁 web前端 js教程 權限管理模組中動態載入Vue組件實例詳解

權限管理模組中動態載入Vue組件實例詳解

Jan 16, 2018 pm 05:09 PM
載入 動態 模組

本系列文章並不是手把手的教程,主要介紹了核心思路並講解了核心代碼,完整的代碼小伙伴們可以在GitHub上star並clone下來研究。另外,原本打算把項目跑起來放到網上供小伙伴們查看,但是之前買服務器為了省錢,內存只有512M,兩個應用跑不起來(已經有一個V部落開源項目在運行),因此小伙伴們只能將就看一下下面的截圖了,GitHub上有部署教程,部署到本地也可以查看完整效果。


專案網址:https://github.com/lenve/vhr

前面幾篇文章,我們基本上已經解決了服務端的問題,並封裝了前端請求,本文我們主要來聊聊登入以及元件的動態載入。

本文是本系列的第五篇,建議先閱讀前面的文章有助於更好的理解本文:

1. SpringBoot+Vue前後端分離,使用SpringSecurity完美處理權限問題(一)  
2.SpringBoot+Vue前後端分離,使用SpringSecurity完美處理權限問題(二)  
3.SpringSecurity中密碼加鹽與SpringBoot中異常統一處理 
4.axios請求封裝與異常統一處理

#登入狀態保存

當使用者登入成功之後,需要將目前使用者的登入資訊保存在本地,方便後面使用。具體實現如下:

登入成功保存資料

#在登入作業執行成功之後,透過commit作業將資料提交到store中,核心程式碼如下:

<span style="font-size: 14px;">this.postRequest('/login', {<br>    username: this.loginForm.username,<br>    password: this.loginForm.password<br>}).then(resp=> {<br>    if (resp && resp.status == 200) {<br>    var data = resp.data;<br>    _this.$store.commit('login', data.msg);<br>    var path = _this.$route.query.redirect;<br>    _this.$router.replace({path: path == '/' || path == undefined ? '/home' : path});<br>    }<br>});<br></span>
登入後複製

store

#store的核心程式碼如下:

<span style="font-size: 14px;">export default new Vuex.Store({<br>  state: {<br>    user: {<br>      name: window.localStorage.getItem('user' || '[]') == null ? '未登录' : JSON.parse(window.localStorage.getItem('user' || '[]')).name,<br>      userface: window.localStorage.getItem('user' || '[]') == null ? '' : JSON.parse(window.localStorage.getItem('user' || '[]')).userface<br>    }<br>  },<br>  mutations: {<br>    login(state, user){<br>      state.user = user;<br>      window.localStorage.setItem('user', JSON.stringify(user));<br>    },<br>    logout(state){<br>      window.localStorage.removeItem('user');<br>    }<br>  }<br>});<br></span>
登入後複製

為了減少麻煩,使用者登入成功後的資料將被保存在localStorage中(防止使用者按F5刷新之後資料遺失),以字串的形式存入,取的時候再轉為json。當使用者登出登陸時,將localStorage中的資料清除。

元件動態載入

在權限管理模組中,這算是前端的核心了。

核心思路

用戶在登入成功之後,進入home主頁之前,向服務端發送請求,要求取得當前的選單資訊和元件訊息,服務端根據目前使用者所具備的角色,以及角色所對應的資源,傳回一個json字串,格式如下:

<span style="font-size: 14px;">[<br>    {<br>        "id": 2,<br>        "path": "/home",<br>        "component": "Home",<br>        "name": "员工资料",<br>        "iconCls": "fa fa-user-circle-o",<br>        "children": [<br>            {<br>                "id": null,<br>                "path": "/emp/basic",<br>                "component": "EmpBasic",<br>                "name": "基本资料",<br>                "iconCls": null,<br>                "children": [],<br>                "meta": {<br>                    "keepAlive": false,<br>                    "requireAuth": true<br>                }<br>            },<br>            {<br>                "id": null,<br>                "path": "/emp/adv",<br>                "component": "EmpAdv",<br>                "name": "高级资料",<br>                "iconCls": null,<br>                "children": [],<br>                "meta": {<br>                    "keepAlive": false,<br>                    "requireAuth": true<br>                }<br>            }<br>        ],<br>        "meta": {<br>            "keepAlive": false,<br>            "requireAuth": true<br>        }<br>    }<br>]<br></span>
登入後複製

前端在拿到這個字串之後,做兩件事:1.將json動態加入到目前路由;2.將資料儲存到store中,然後各頁根據store中的資料來渲染選單。

核心想法並不難,下面我們來看看實作步驟。

資料請求時機

這很重要。

可能會有小夥伴說這有何難,登入成功之後請求不就可以了嗎?是的,登入成功之後,請求選單資源是可以的,請求到之後,我們將之保存在store中,以便下一次使用,但是這樣又會有另外一個問題,假如用戶登入成功之後,點擊某一個子頁面,進入子頁面中,然後按了一下F5進行刷新,這個時候就GG了,因為F5刷新之後store中的資料就沒了,而我們又只在登入成功的時候請求了一次選單資源,要要解決這個問題,有兩種想法:1.將選單資源不要儲存到store中,而是儲存到localStorage中,這樣即使F5刷新之後資料還在;2.直接在每一個頁面的mounted方法中,都去載入一次選單資源。

由於選單資源是非常敏感的,因此最好不要將其保存到本地,故捨棄方案1,但是方案2的工作量有點大,因此我採取辦法將之簡化,採取的辦法就是使用路由中的導航守衛。

路由導航守衛

我的具體實作是這樣的,首先在store中建立一個routes數組,這是一個空數組,然後開啟路由全域守衛,如下:

<span style="font-size: 14px;">router.beforeEach((to, from, next)=> {<br>    if (to.name == 'Login') {<br>      next();<br>      return;<br>    }<br>    var name = store.state.user.name;<br>    if (name == '未登录') {<br>      if (to.meta.requireAuth || to.name == null) {<br>        next({path: '/', query: {redirect: to.path}})<br>      } else {<br>        next();<br>      }<br>    } else {<br>      initMenu(router, store);<br>      next();<br>    }<br>  }<br>)<br></span>
登入後複製

這裡的程式碼很短,我來做一個簡單的解釋:  
1.如果要去的頁面是登入頁面,這個沒啥好說的,直接過。

2.如果不是登录页面的话,我先从store中获取当前的登录状态,如果未登录,则通过路由中meta属性的requireAuth属性判断要去的页面是否需要登录,如果需要登录,则跳回登录页面,同时将要去的页面的path作为参数传给登录页面,以便在登录成功之后跳转到目标页面,如果不需要登录,则直接过(事实上,本项目中只有Login页面不需要登录);如果已经登录了,则先初始化菜单,再跳转。

初始化菜单的操作如下:

<span style="font-size: 14px;">export const initMenu = (router, store)=> {<br>  if (store.state.routes.length > 0) {<br>    return;<br>  }<br>  getRequest("/config/sysmenu").then(resp=> {<br>    if (resp && resp.status == 200) {<br>      var fmtRoutes = formatRoutes(resp.data);<br>      router.addRoutes(fmtRoutes);<br>      store.commit('initMenu', fmtRoutes);<br>    }<br>  })<br>}<br>export const formatRoutes = (routes)=> {<br>  let fmRoutes = [];<br>  routes.forEach(router=> {<br>    let {<br>      path,<br>      component,<br>      name,<br>      meta,<br>      iconCls,<br>      children<br>    } = router;<br>    if (children && children instanceof Array) {<br>      children = formatRoutes(children);<br>    }<br>    let fmRouter = {<br>      path: path,<br>      component(resolve){<br>        if (component.startsWith("Home")) {<br>          require(['../components/' + component + '.vue'], resolve)<br>        } else if (component.startsWith("Emp")) {<br>          require(['../components/emp/' + component + '.vue'], resolve)<br>        } else if (component.startsWith("Per")) {<br>          require(['../components/personnel/' + component + '.vue'], resolve)<br>        } else if (component.startsWith("Sal")) {<br>          require(['../components/salary/' + component + '.vue'], resolve)<br>        } else if (component.startsWith("Sta")) {<br>          require(['../components/statistics/' + component + '.vue'], resolve)<br>        } else if (component.startsWith("Sys")) {<br>          require(['../components/system/' + component + '.vue'], resolve)<br>        }<br>      },<br>      name: name,<br>      iconCls: iconCls,<br>      meta: meta,<br>      children: children<br>    };<br>    fmRoutes.push(fmRouter);<br>  })<br>  return fmRoutes;<br>}<br></span>
登入後複製

在初始化菜单中,首先判断store中的数据是否存在,如果存在,说明这次跳转是正常的跳转,而不是用户按F5或者直接在地址栏输入某个地址进入的。否则就去加载菜单。拿到菜单之后,首先通过formatRoutes方法将服务器返回的json转为router需要的格式,这里主要是转component,因为服务端返回的component是一个字符串,而router中需要的却是一个组件,因此我们在formatRoutes方法中动态的加载需要的组件即可。数据格式准备成功之后,一方面将数据存到store中,另一方面利用路由中的addRoutes方法将之动态添加到路由中。

菜单渲染

最后,在Home页中,从store中获取菜单json,渲染成菜单即可,相关代码可以在<span style="font-size: 14px;">Home.vue</span>中查看,不赘述。

OK,如此之后,不同用户登录成功之后就可以看到不同的菜单了。

相关推荐:

vue组件之Alert详解

jquery加载单文件vue组件方法分享

实例详解vue组件父子间通信之聊天室


以上是權限管理模組中動態載入Vue組件實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

WLAN擴充模組已停止[修復] WLAN擴充模組已停止[修復] Feb 19, 2024 pm 02:18 PM

如果您的Windows電腦上的WLAN擴充模組出現問題,可能會導致您與網際網路中斷連線。這種情況常常讓人感到困擾,但幸運的是,本文提供了一些簡單的建議,可以幫助您解決這個問題,讓您的無線連線重新正常運作。修復WLAN擴充模組已停止如果您的Windows電腦上的WLAN可擴充性模組已停止運作,請依照下列建議進行修復:執行網路和Internet故障排除程式停用並重新啟用無線網路連線重新啟動WLAN自動設定服務修改電源選項修改高級電源設定重新安裝網路適配器驅動程式運行一些網路命令現在,讓我們來詳細看

WLAN可擴充性模組無法啟動 WLAN可擴充性模組無法啟動 Feb 19, 2024 pm 05:09 PM

本文詳細介紹了解決事件ID10000的方法,該事件表明無線區域網路擴充模組無法啟動。在Windows11/10PC的事件日誌中可能會顯示此錯誤。 WLAN可擴充性模組是Windows的一個元件,允許獨立硬體供應商(IHV)和獨立軟體供應商(ISV)為使用者提供客製化的無線網路特性和功能。它透過增加Windows預設功能來擴充本機Windows網路元件的功能。在作業系統載入網路元件時,WLAN可擴充性模組會作為初始化的一部分啟動。如果無線區域網路擴充模組遇到問題無法啟動,您可能會在事件檢視器的日誌中看到錯誤消

將VirtualBox固定磁碟轉換為動態磁碟,反之亦然 將VirtualBox固定磁碟轉換為動態磁碟,反之亦然 Mar 25, 2024 am 09:36 AM

在建立虛擬機器時,系統會要求您選擇磁碟類型,您可以選擇固定磁碟或動態磁碟。如果您選擇了固定磁碟,後來意識到需要動態磁碟,或者相反,該怎麼辦?好!你可以把一種轉換成另一種。在這篇文章中,我們將看到如何將VirtualBox固定磁碟轉換為動態磁碟,反之亦然。動態磁碟是一種虛擬硬碟,它最初具有較小的大小,隨著您在虛擬機器中儲存數據,其大小會相應增長。動態磁碟在節省儲存空間方面非常高效,因為它們只佔用所需的主機儲存空間。然而,隨著磁碟容量的擴展,可能會稍微影響電腦的效能。固定磁碟和動態磁碟是虛擬機器中常用的

如何在 Windows 11 上將動態磁碟轉換為基本磁碟 如何在 Windows 11 上將動態磁碟轉換為基本磁碟 Sep 23, 2023 pm 11:33 PM

如果要在Windows11中將動態磁碟轉換為基本磁碟,則應先建立備份,因為該程序將擦除其中的所有資料。為什麼要在Windows11中將動態磁碟轉換為基本磁碟?根據Microsoft,動態磁碟已從Windows中棄用,不再建議使用。此外,Windows家庭版不支援動態磁碟,因此您將無法存取這些邏輯磁碟機。如果要將更多磁碟合併到更大的磁碟區中,建議使用基本磁碟或儲存空間。在本文中,我們將向您展示如何在Windows11上將動態磁碟轉換為基本磁碟如何在Windows11中將動態磁碟轉換為基本磁碟?在開始

在Illustrator中載入插件時出錯[修復] 在Illustrator中載入插件時出錯[修復] Feb 19, 2024 pm 12:00 PM

啟動AdobeIllustrator時是否會彈出載入插件時出錯的訊息?一些Illustrator用戶在打開該應用程式時遇到了此錯誤。訊息後面緊跟著一系列有問題的插件。此錯誤提示表示已安裝的插件有問題,但也可能是由於VisualC++DLL檔案損壞或首選項檔案受損等其他原因所引起。如果遇到此錯誤,我們將在本文中指導您修復問題,請繼續閱讀以下內容。在Illustrator中載入外掛程式時出錯如果您在嘗試啟動AdobeIllustrator時收到「載入外掛程式時出錯」的錯誤訊息,您可以使用以下用途:以管理員身

Stremio字幕不工作;載入字幕時出錯 Stremio字幕不工作;載入字幕時出錯 Feb 24, 2024 am 09:50 AM

字幕在你的WindowsPC上不能在Stremio上運行嗎?一些Stremio用戶報告說,影片中沒有顯示字幕。許多用戶報告說他們遇到了一條錯誤訊息,上面寫著「載入字幕時出錯」。以下是與此錯誤一起顯示的完整錯誤訊息:載入字幕時出錯載入字幕失敗:這可能是您正在使用的插件或您的網路有問題。正如錯誤訊息所說,可能是您的網路連線導致了錯誤。因此,請檢查您的網路連接,並確保您的網路運作正常。除此之外,這個錯誤的背後可能還有其他原因,包括字幕加載項衝突、特定影片內容不支援字幕以及Stremio應用程式過時。如

PHP實作無限滾動加載 PHP實作無限滾動加載 Jun 22, 2023 am 08:30 AM

隨著互聯網的發展,越來越多的網頁需要支援滾動加載,而無限滾動加載是其中的一種。它可以讓頁面不斷載入新的內容,使用戶可以更流暢地瀏覽網頁。在這篇文章中,我們將介紹如何使用PHP實現無限滾動載入。一、什麼是無限滾動載入?無限滾動載入是一種基於捲軸的網頁內容載入方式。它的原理是當使用者捲動至頁面底部時,透過AJAX非同步調取後台數據,實現不斷載入新的內容。這種載入方

插入超連結時Outlook凍結 插入超連結時Outlook凍結 Feb 19, 2024 pm 03:00 PM

如果您在插入超連結時出現在Outlook時遇到凍結問題,可能是因為網路連線不穩定、Outlook版本舊、防毒軟體幹擾或加載項衝突等原因。這些因素可能導致Outlook無法正常處理超連結操作。修正插入超連結時Outlook凍結的問題使用以下修復程式解決插入超連結時Outlook凍結的問題:檢查已安裝的加載項更新Outlook暫時停用您的防毒軟體,然後嘗試建立新的使用者設定檔修復辦公室應用程式卸載並重新安裝Office我們開始吧。 1]檢查已安裝的加載項可能是Outlook中安裝的某個加載項導致了問題。

See all articles