Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung des dynamischen Ladens von Vue-Komponenteninstanzen im Berechtigungsverwaltungsmodul

Detaillierte Erläuterung des dynamischen Ladens von Vue-Komponenteninstanzen im Berechtigungsverwaltungsmodul

小云云
小云云Original
2018-01-16 17:09:312002Durchsuche

Bei dieser Artikelserie handelt es sich nicht um eine Schritt-für-Schritt-Anleitung. Sie stellt hauptsächlich die Kernideen vor und erklärt den Kerncode. Freunde können den vollständigen Code auf GitHub markieren und klonen. Außerdem hatte ich ursprünglich geplant, das Projekt auszuführen und online zu stellen, damit Freunde es sehen können. Um jedoch vor dem Kauf eines Servers Geld zu sparen, betrug der Speicher nur 512 MB und die beiden Anwendungen konnten nicht ausgeführt werden (es gibt bereits einen V-Stamm). Open-Source-Projekt läuft), also können wir uns nur den Screenshot unten ansehen. Es gibt ein Bereitstellungs-Tutorial auf GitHub. Sie können den vollständigen Effekt auch durch lokale Bereitstellung anzeigen.


Projektadresse: https://github.com/lenve/vhr

Wir haben im Grunde die vorherigen Artikel gelöst. Es löst serverseitige Probleme und kapselt Front-End-Anfragen. In diesem Artikel sprechen wir hauptsächlich über die Anmeldung und das dynamische Laden von Komponenten.

Dieser Artikel ist der fünfte in dieser Reihe. Es wird empfohlen, zuerst die vorherigen Artikel zu lesen, um diesen Artikel besser zu verstehen:

1. SpringBoot+Vue trennt das Front- und Back-End und verwendet SpringSecurity, um Berechtigungsprobleme perfekt zu behandeln (1)
2. SpringBoot+Vue trennt das Front- und Back-End und verwendet SpringSecurity, um Berechtigungsprobleme perfekt zu behandeln (2)
3. Passwort-Salting in SpringSecurity und SpringBoot Einheitliche Ausnahmebehandlung
4.axios-Anforderungskapselung und einheitliche Ausnahmebehandlung

Anmeldestatus speichern

Nachdem sich der Benutzer erfolgreich angemeldet hat, müssen die Anmeldeinformationen des aktuellen Benutzers zur späteren Verwendung lokal gespeichert werden. Die spezifische Implementierung lautet wie folgt:

Bei erfolgreicher Anmeldung werden Daten gespeichert

Nachdem der Anmeldevorgang erfolgreich ausgeführt wurde, werden die Daten an die übermittelt Store durch den Commit-Vorgang. Der Kerncode lautet wie folgt:

<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

Der Kerncode von store lautet wie folgt :

<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>

Um Probleme zu reduzieren, werden die Daten nach erfolgreicher Anmeldung des Benutzers in localStorage gespeichert (um Datenverlust zu verhindern, nachdem der Benutzer F5 zum Aktualisieren gedrückt hat). in Form einer Zeichenfolge und wird dann beim Abruf in JSON konvertiert. Wenn sich der Benutzer abmeldet, löschen Sie die Daten in localStorage.

Dynamisches Laden von Komponenten

Im Rechteverwaltungsmodul ist dies der Kern des Frontends.

Kernidee

Nachdem sich der Benutzer erfolgreich angemeldet hat, sendet der Benutzer vor dem Aufrufen der Startseite eine Anfrage an den Server, um die zu erhalten Aktuelle Menüinformationen und Komponenteninformationen: Der Server gibt eine JSON-Zeichenfolge basierend auf der Rolle des aktuellen Benutzers und den der Rolle entsprechenden Ressourcen zurück. Das Format lautet wie folgt:

<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>

Das Frontend erhält dieses Zeichen. Führen Sie nach der Zeichenfolge zwei Dinge aus: 1. Fügen Sie JSON dynamisch zur aktuellen Route hinzu. 2. Speichern Sie die Daten im Store. Anschließend rendert jede Seite das Menü basierend auf den Daten im Store.

Die Kernidee ist nicht schwierig. Werfen wir einen Blick auf die Umsetzungsschritte.

Zeitpunkt der Datenanforderung

Dies ist sehr wichtig.

Einige Freunde fragen sich vielleicht, warum das so schwierig ist. Kann ich es nicht einfach anfordern, nachdem ich mich erfolgreich angemeldet habe? Ja, es ist möglich, nach erfolgreicher Anmeldung Menüressourcen anzufordern. Nachdem die Anfrage eingegangen ist, speichern wir sie für die nächste Verwendung. Es tritt jedoch ein weiteres Problem auf, wenn der Benutzer nach erfolgreicher Anmeldung auf ein bestimmtes untergeordnetes Element klickt Melden Sie sich an, Seite, geben Sie die Unterseite ein und drücken Sie dann F5 zum Aktualisieren. Zu diesem Zeitpunkt ist es GG, da die Daten im Speicher nach der Aktualisierung mit F5 verschwunden sind und wir die Menüressourcen nur einmal beim Anmelden angefordert haben ist erfolgreich. Es gibt zwei Ideen, um dieses Problem zu lösen: 1. Speichern Sie die Menüressourcen nicht im Store, sondern in localStorage, damit die Daten auch nach der Aktualisierung mit F5 noch vorhanden sind. 2. Direkt in der gemounteten Methode Gehen Sie auf jeder Seite einmal zu „Menüressourcen laden“.

Da die Menüressourcen sehr sensibel sind, ist es am besten, sie nicht lokal zu speichern, daher habe ich Option 1 aufgegeben. Option 2 ist jedoch etwas arbeitsintensiv, also habe ich einen Schritt unternommen Um es lokal zu speichern, verwenden Sie den Navigationsschutz beim Routing.

Route Navigation Guard

Meine spezifische Implementierung sieht wie folgt aus: Erstellen Sie zunächst ein Routen-Array im Store, bei dem es sich um ein leeres Array handelt. Aktivieren Sie dann den globalen Routingschutz wie folgt:

<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>

Der Code hier ist sehr kurz, lassen Sie mich eine einfache Erklärung geben:
1 Gehe zu ist die Anmeldeseite, dazu gibt es nichts zu sagen, mach einfach weiter.

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组件父子间通信之聊天室


Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des dynamischen Ladens von Vue-Komponenteninstanzen im Berechtigungsverwaltungsmodul. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn