Vue-Router-Beispielcode zum dynamischen Generieren von Navigationsmenüs basierend auf Backend-Berechtigungen

Vue-Router-Beispielcode zum dynamischen Generieren von Navigationsmenüs basierend auf Backend-Berechtigungen

Vue.js

  • Vue-Router
  • vuex

1. Global Guard registrieren

Kernlogik
1. Token-Authentifizierung (Backend) => Zurück zur Anmeldeseite, wenn das Token ungültig ist
2. Benutzerberechtigungen einholen
3. Berechtigungen prüfen und Routing-Menüs dynamisch hinzufügen

router.beforeResolve registriert einen globalen Schutz. Ähnlich wie router.beforeEach, außer dass Resolve Guards aufgerufen werden, bevor die Navigation bestätigt wird und nachdem alle Component Guards und asynchronen Routenkomponenten aufgelöst wurden.

router.beforeResolve(async (zu, von, weiter) => {
  let hasToken = store.getters['Benutzer/Zugriffstoken']
  wenn (!settings.loginInterception) hasToken = true
  wenn (hatToken) {
    wenn (zu.Pfad === '/auth/sign-in') {
      weiter({ Pfad: '/' })
    } anders {
      const hatBerechtigungen =
        store.getters['Benutzer/Berechtigungen'] &&
        store.getters['Benutzer/Berechtigungen'].length > 0
      wenn (hatBerechtigungen) {
        nächste()
      } anders {
        versuchen {
          Berechtigungen lassen
          wenn (!constant.loginInterception) {
            // settings.js Wenn loginInterception false ist, virtuelle Berechtigungen erstellen, warten Sie auf store.dispatch('User/setPermissions', ['admin'])
            Berechtigungen = ['Administrator']
          } anders {
            Berechtigungen = warte auf store.dispatch('User/getUserInfo')
          }
          let accessRoutes = []
          accessRoutes = warte auf store.dispatch('Routes/setRoutes', Berechtigungen)
          // Routen hinzufügen router.addRoutes(accessRoutes)
          weiter({ ...zu, ersetzen: true })
        } fangen {
          warte auf store.dispatch('Benutzer/Zugriffstoken zurücksetzen')
        }
      }
    }
  } anders {
    wenn (settings.routesWhiteList.indexOf(to.path) !== -1) {
      nächste()
    } anders {
      weiter('/auth/anmelden')
    }
  }
  Dokumenttitel = getPageTitle(zu.meta.title)
})

settings.js globale Einstellungen

Standard exportieren {
  // Ob Login-Interception aktiviert werden soll loginInterception: true,
  // Routen, die die Token-Verifizierung nicht bestehen routesWhiteList: ['/auth/sign-in', '/auth/register', '/401', '/404'],
}

2. Globale Cache-Routen der Vuex-Statusverwaltung

  • Status: globale Speicherung von Daten
  • Getter: kann als berechnet verstanden werden, der die Daten berechnet
  • Mutationen: Synchrone Änderungen an Daten
  • Aktionen: Asynchrone Änderungen an Daten (Implementieren asynchroner Operationen)
  • Modul: Teilen Sie den Shop in Module auf
/**
 * @Autor Alan
 * @description Routing-Abfangstatusverwaltung*/
importiere { asyncRoutes, constantRoutes } von '@/router'
importiere { filterAsyncRoutes } von '@/Utils/handleRoutes'

const state = () => ({
  Routen: [],
  Teilrouten: []
})
const getter = {
  Routen: (Bundesstaat) => Bundesstaat.Routen,
  partielleRouten: (Staat) => Staat.partielleRouten
}
const Mutationen = {
  setRoutes (Staat, Routen) {
    Zustand.Routen = konstanteRouten.concat(Routen)
  },

  setPartialRoutes (Status, Routen) {
    Zustand.partielleRouten = konstanteRouten.concat(Routen)
  }
}
const Aktionen = {
  async setRoutes ({ commit }, Berechtigungen) {
    const finallyAsyncRoutes = warte auf filterAsyncRoutes(
      [...asynchroneRouten],
      Berechtigungen
    )
    commit('setRoutes', schließlichAsyncRoutes)
    returniere finallyAsyncRoutes
  },
  setPartialRoutes ({ commit }, accessRoutes) {
    commit('partielleRouten festlegen', Zugriffsrouten)
    zurück zu den Zugangsrouten
  }
}
export default { namespaced: true, Status, Getter, Mutationen, Aktionen }

3. Routing-Abfangen

/**
 * @Autor Alan
 * @description Bestimmen Sie, ob die aktuelle Route Berechtigungen enthält * @param Berechtigungen
 * @param Route
 * @returns {boolean|*}
 */
Exportfunktion hasPermission (Berechtigungen, Route) {
  wenn (route.meta && route.meta.permissions) {
    returniere Berechtigungen.some((Rolle) => route.meta.permissions.includes(Rolle))
  } anders {
    returniere wahr
  }
}

/**
 * @Autor Alan
 * @description Routen basierend auf dem Berechtigungsarray abfangen * @param Routen
 * @param-Berechtigungen
 * @returns {[]}
 */
Exportfunktion filterAsyncRoutes (Routen, Berechtigungen) {
  const finallyRoutes = []
  Routen.fürJeden((Route) => {
    const item = { ...route }
    if (hasPermission(Berechtigungen, Element)) {
      wenn (Element.Kinder) {
        item.children = filterAsyncRoutes(item.children, Berechtigungen)
      }
      finallyRoutes.push(Element)
    }
  })
  return finallyRoutes
}

4. Routing-Menü

/*
* @Autor Alan
* @description Öffentliches Routing */
exportiere const konstanteRouten = [
  {
    Pfad: '/auth',
    Name: 'auth1',
    Komponente: AuthLayout,
    untergeordnete Elemente: authChildRoutes('auth1'),
    hidden: true // Menü ausblenden},
  {
    Weg: '/',
    Name: "Dashboard",
    Komponente: VerticleLayout,
    Meta: {
      Titel: 'Dashboard',
      Name: „sidebar.dashboard“,
      is_heading: falsch,
      is_active: falsch,
      Link: '',
      Klassenname: '',
      is_icon_class: wahr,
      Symbol: „ri-home-4-line“,
      Berechtigungen: ['admin']
    },
    untergeordnete Elemente: childRoutes('dashboard')
  }
]

/*
* @Autor Alan
* @description Asynchrones Routing */
exportiere const asyncRoutes = [
  {
    Pfad: '/menu-design',
    Name: 'horizontales Dashboard',
    Komponente: HorizantalLayout,
    Meta: {
      Titel: 'Menügestaltung',
      Name: 'sidebar.MenüDesign',
      is_heading: falsch,
      is_active: falsch,
      Link: '',
      Klassenname: '',
      is_icon_class: wahr,
      Symbol: „ri-menu-3-line“,
      Berechtigungen: ['admin']
    },
    untergeordnete Elemente: horizontaleRoute('Dashboard')
  }, {
    Pfad: '/core',
    Name: "Kern",
    Komponente: VerticleLayout,
    Meta: {
      Titel: „UI-Elemente“,
      Name: 'sidebar.uiElements',
      is_heading: falsch,
      is_active: falsch,
      Klassenname: '',
      Link: '',
      is_icon_class: wahr,
      Symbol: „ri-Bleistift-Lineal-Linie“,
      Berechtigungen: ['admin']
    },
    Kinder: coreChildRoute('core')
  }
]

5. Rekursive Menü-Vue-Komponente

<Vorlage>
  <b-collapse tag="ul" :class="Klassenname" :visible="öffnen" :id="ID-Name" :accordion="AccordianName">
    <li v-for="(Artikel, Index) in Artikeln" :key="index" :class=" !hideListMenuTitle? 'p-0' : Artikel.meta.is_heading ? 'iq-menu-title' :activeLink(Artikel) && Artikel.Kinder ? 'aktiv' : activeLink(Artikel) ? 'aktiv' : ''">
      <template v-if="!item.hidden">
        <i v-if="item.meta.is_heading && hideListMenuTitle" Klasse="ri-subtract-line" />
        <span v-if="item.meta.is_heading && hideListMenuTitle">{{ $t(item.meta.name) }}</span>
        <router-link :to="item.meta.link" v-if="!item.is_heading" :class="`iq-waves-effect ${activeLink(item) && item.children ? 'active' : activeLink(item) ? 'active' : ''}`" vb-toggle="item.meta.name">
          <i :class="item.meta.icon" v-if="item.meta.ist_icon_klasse"/>
          <Vorlage v-else v-html="item.meta.icon">
          </Vorlage>
          <span>{{ $t(item.meta.name) }}</span>
          <i v-if="Artikel.Kinder" Klasse="ri-Pfeil-rechts-s-Linie iq-Pfeil-rechts" />
          <small v-html="item.meta.append" v-if="hideListMenuTitle" :class="item.meta.append_class" />
        </Router-Link>
        <Liste v-if="item.children" :items="item.children" :sidebarGroupTitle="hideListMenuTitle" :open="item.meta.link.name !== '' && activeLink(item) && item.children ? true : !!(item.meta.link.name !== '' && activeLink(item))" :idName="item.meta.name" :accordianName="`sidebar-accordion-${item.meta.class_name}`" :className="`iq-submenu ${item.meta.class_name}`" />
      </Vorlage>
    </li>
  </b-collapse>
</Vorlage>
<Skript>
Liste importieren aus './CollapseMenu' // Selbstkomponente importieren { core } aus '../../../config/pluginInit'
Standard exportieren {
  Namensliste',
  Requisiten: {
    Elemente: Array,
    Klassenname: { Typ: String, Standard: 'iq-menu' },
    öffnen: { Typ: Boolean, Standard: false },
    idName: { Typ: String, Standard: 'Seitenleiste' },
    Akkordeonname: { Typ: String, Standard: 'Seitenleiste' },
    sidebarGroupTitle: { Typ: Boolean, Standard: true }
  },
  Komponenten:
    Liste
  },
  berechnet: {
    Listenmenütitel ausblenden() {
      gib diesen.sidebarGroupTitle zurück
    }
  },
  montiert () {
  },
  Methoden: {
    activeLink (Element) {
      returniere core.getActiveLink(Element, this.$route.name)
    }
  }
}
</Skript>

Dies ist das Ende dieses Artikels über den Beispielcode des Vue-Routers, der dynamisch ein Navigationsmenü basierend auf Backend-Berechtigungen generiert. Weitere relevante Inhalte zum Navigationsmenü mit Vue-Router-Berechtigungen finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Verwenden Sie das Vue-Element-Admin-Framework, um die Menüfunktion dynamisch vom Backend abzurufen
  • Beispiel für die dynamische Hinzufügung von Routing und Generierung von Menümethoden in Vue
  • So generieren Sie dynamisch Untermenüs in der Vue-Seitenleiste
  • Wie erhält Vue Daten aus dem Hintergrund, um eine dynamische Menüliste zu generieren

<<:  Analyse der allgemeinen Konfigurationsmethoden für virtuelle Hosts von Apache

>>:  Prinzipien der MySQL-Datentypoptimierung

Artikel empfehlen

Was ist HTML?

Geschichte der HTML-Entwicklung: HTML steht im En...

Verwenden Sie die vertikale Ausrichtung, um Eingabe und Bild auszurichten

Wenn Sie Eingabe und Bild in dieselbe Zeile setzen...

Navicat-Remoteverbindung zur MySQL-Implementierungsschritteanalyse

Vorwort Ich glaube, dass jeder auf einem Remote-S...

Unterschiede und Vergleiche von Speicher-Engines in MySQL

MyISAM-Speicher-Engine MyISAM basiert auf der ISA...

Lernen Sie schnell die MySQL-Grundlagen

Inhaltsverzeichnis SQL verstehen SELECT verstehen...

Beispielcode einer in Vue3 gekapselten Lupenkomponente

Inhaltsverzeichnis Komponenteninfrastruktur Zweck...

Detaillierte Beschreibung der Funktion von new in JS

Inhaltsverzeichnis 1. Beispiel 2. Erstelle 100 So...

Details zur Verwendung der JS-Tag-Syntax

Inhaltsverzeichnis 1. Einführung in Label-Anweisu...

Installations-JDK-Tutorialanalyse für Linux-System (Centos6.5 und höher)

Artikelstruktur 1. Vorbereitung 2. Installieren S...

Ubuntu 19.04 Installationstutorial (Schritte in Bild und Text)

1. Vorbereitung 1.1 Laden Sie VMware 15 herunter ...

Implementierungsschritte zum Erstellen eines FastDFS-Dateiservers unter Linux

Inhaltsverzeichnis 1. Softwarepaket 2. Installier...

So konfigurieren Sie die CDN-Planung mit dem Modul Nginx_geo

Einführung in das Geo-Modul von Nginx Die Geo-Dir...