バックエンドの権限に基づいてナビゲーション メニューを動的に生成する Vue-router のサンプル コード

バックエンドの権限に基づいてナビゲーション メニューを動的に生成する Vue-router のサンプル コード

js の

  • vue-ルーター
  • ヴュークス

1. グローバルガードを登録する

コアロジック
1. トークン認証(バックエンド) => トークンが無効な場合はログインページに戻る
2. ユーザー権限を取得する
3. 権限を確認し、ルーティングメニューを動的に追加する

router.beforeResolve はグローバル ガードを登録します。 router.beforeEach と似ていますが、ナビゲーションが確認される前、およびすべてのコンポーネント ガードと非同期ルート コンポーネントが解決された後に、解決ガードが呼び出される点が異なります。

router.beforeResolve(async (to, from, next) => {
  hasToken = store.getters['User/accessToken'] とします。
  if (!settings.loginInterception) hasToken = true
  (トークンを持っている場合){
    to.path === '/auth/sign-in'の場合{
      次へ({ パス: '/' })
    } それ以外 {
      定数hasPermissions =
        store.getters['ユーザー/権限'] &&
        store.getters['ユーザー/権限'].length > 0
      権限がある場合
        次()
      } それ以外 {
        試す {
          許可を与える
          定数ログインインターセプションの場合{
            // settings.js loginInterception が false の場合、仮想権限を作成します。await store.dispatch('User/setPermissions', ['admin'])
            権限 = ['管理者']
          } それ以外 {
            権限 = store.dispatch('User/getUserInfo') を待機します
          }
          accessRoutes = [] とします
          accessRoutes = store.dispatch('Routes/setRoutes', 権限) を待機します
          // ルートを追加する router.addRoutes(accessRoutes)
          次({ ...to, 置き換え: true })
        } キャッチ {
          store.dispatch('User/resetAccessToken') を待機します。
        }
      }
    }
  } それ以外 {
    (settings.routesWhiteList.indexOf(to.path) !== -1) の場合 {
      次()
    } それ以外 {
      次へ('/auth/sign-in')
    }
  }
  document.title = getPageTitle(to.meta.title)
})

settings.js グローバル設定

エクスポートデフォルト{
  // ログインインターセプションを有効にするかどうか loginInterception: true,
  // トークン検証に合格しないルートroutesWhiteList: ['/auth/sign-in', '/auth/register', '/401', '/404'],
}

2. Vuex 状態管理グローバルキャッシュルート

  • 状態: データのグローバルストレージ
  • ゲッター: 計算されたものと理解でき、データを計算する
  • 突然変異: データへの同期的な変更
  • アクション: データへの非同期変更 (非同期操作の実装)
  • モジュール: ストアをモジュールに分割する
/**
 * @著者 アラン
 * @description ルーティングインターセプトステータス管理*/
'@/router' から { asyncRoutes, constantRoutes } をインポートします。
'@/Utils/handleRoutes' から { filterAsyncRoutes } をインポートします。

定数状態 = () => ({
  ルート: [],
  部分ルート: []
})
const ゲッター = {
  ルート: (状態) => state.routes、
  部分ルート: (状態) => state.partialRoutes
}
const 変異 = {
  setRoutes (状態、ルート) {
    state.routes = constantRoutes.concat(routes)
  },

  setPartialRoutes (状態、ルート) {
    state.partialRoutes = constantRoutes.concat(ルート)
  }
}
定数アクション = {
  非同期setRoutes({コミット}、権限){
    const finallyAsyncRoutes = filterAsyncRoutesを待機します(
      [...asyncRoutes]、
      権限
    )
    コミット('setRoutes'、finallyAsyncRoutes)
    finallyAsyncRoutes を返す
  },
  setPartialRoutes ({ commit }, accessRoutes) {
    コミット('setPartialRoutes'、アクセスルート)
    アクセスルートを返す
  }
}
エクスポート デフォルト { namespaced: true, state, getters, mutations, actions }

3. ルーティング傍受

/**
 * @著者 アラン
 * @description 現在のルートに権限が含まれているかどうかを判定します* @param 権限
 * @param ルート
 * @returns {ブール値|*}
 */
エクスポート関数hasPermission(権限、ルート){
  ルートメタの場合、ルートメタのパーミッションは次のようになります。
    権限を返します。(ロール) => route.meta.permissions.includes(ロール))
  } それ以外 {
    真を返す
  }
}

/**
 * @著者 アラン
 * @description 権限配列に基づいてルートをインターセプトします * @param ルート
 * @param 権限
 * @returns {[]}
 */
エクスポート関数 filterAsyncRoutes (ルート、権限) {
  const finallyRoutes = []
  ルート.forEach((ルート) => {
    const アイテム = { ...ルート }
    if (hasPermission(権限, アイテム)) {
      if (item.children) {
        item.children = filterAsyncRoutes(item.children, 権限)
      }
      最後にルートをプッシュします(アイテム)
    }
  })
  finallyRoutes を返す
}

4. ルーティングメニュー

/*
* @著者 アラン
* @description パブリックルーティング */
エクスポートconst constantRoutes = [
  {
    パス: '/auth',
    名前: 'auth1',
    コンポーネント: AuthLayout、
    子: authChildRoutes('auth1'),
    hidden: true // メニューを非表示にする},
  {
    パス: '/'、
    名前: 'ダッシュボード'、
    コンポーネント: VerticleLayout、
    メタ: {
      タイトル:「ダッシュボード」
      名前: 'sidebar.dashboard',
      is_heading: 偽、
      is_active: 偽、
      リンク: ''、
      クラス名: ''、
      is_icon_class: true、
      アイコン: 'ri-home-4-line',
      権限: ['admin']
    },
    子: childRoutes('dashboard')
  }
]

/*
* @著者 アラン
* @description 非同期ルーティング */
エクスポートconst asyncRoutes = [
  {
    パス: '/menu-design',
    名前: '水平ダッシュボード'、
    コンポーネント: Horizo​​ntalLayout、
    メタ: {
      タイトル:「メニューデザイン」
      名前: 'sidebar.MenuDesign',
      is_heading: 偽、
      is_active: 偽、
      リンク: ''、
      クラス名: ''、
      is_icon_class: true、
      アイコン: 'ri-menu-3-line',
      権限: ['admin']
    },
    子: 水平ルート('ダッシュボード')
  }, {
    パス: '/core',
    名前: 'コア',
    コンポーネント: VerticleLayout、
    メタ: {
      タイトル: 「UI要素」、
      名前: 'sidebar.uiElements',
      is_heading: 偽、
      is_active: 偽、
      クラス名: ''、
      リンク: ''、
      is_icon_class: true、
      アイコン: 'ri-pencil-ruler-line',
      権限: ['admin']
    },
    子: coreChildRoute('core')
  }
]

5. 再帰メニュー Vue コンポーネント

<テンプレート>
  <b-collapse タグ="ul" :class="className" :visible="open" :id="idName" :accordion="accordianName">
    <li v-for="(item,index) in items" :key="index" :class=" !hideListMenuTitle? 'p-0' : item.meta.is_heading ? 'iq-menu-title' :activeLink(item) && item.children ? 'active' : activeLink(item) ? 'active' : ''">
      <テンプレート v-if="!item.hidden">
        <i v-if="item.meta.is_heading && hideListMenuTitle" class="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.is_icon_class"/>
          <テンプレート v-else v-html="item.meta.icon">
          </テンプレート>
          <span>{{ $t(item.meta.name) }}</span>
          <i v-if="item.children" class="ri-arrow-right-s-line iq-arrow-right" />
          <small v-html="item.meta.append" v-if="hideListMenuTitle" :class="item.meta.append_class" />
        </ルーターリンク>
        <リスト 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}`" />
      </テンプレート>
    </li>
  </b-collapse>
</テンプレート>
<スクリプト>
import List from './CollapseMenu' // 自己コンポーネント import { core } from '../../../config/pluginInit'
エクスポートデフォルト{
  名前: 'リスト',
  小道具: {
    アイテム: 配列、
    クラス名: { タイプ: 文字列、デフォルト: 'iq-menu' },
    open: { 型: ブール値、デフォルト: false },
    idName: { タイプ: 文字列、デフォルト: 'サイドバー' },
    accordianName: { タイプ: 文字列、デフォルト: 'sidebar' },
    sidebarGroupTitle: { タイプ: ブール値、デフォルト: true }
  },
  コンポーネント:
    リスト
  },
  計算: {
    リストメニュータイトルを非表示にする() {
      this.sidebarGroupTitle を返す
    }
  },
  マウントされた(){
  },
  メソッド: {
    アクティブリンク (アイテム) {
      core.getActiveLink(item, this.$route.name) を返します
    }
  }
}
</スクリプト>

これで、バックエンドの権限に基づいてナビゲーション メニューを動的に生成する vue-router のサンプル コードに関するこの記事は終了です。vue-router の権限ナビゲーション メニューに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • vue-element-adminフレームワークを使用して、バックエンドからメニュー機能を動的に取得します。
  • Vue のルーティングの動的追加とメニューメソッドの生成の例
  • Vue サイドバーでサブメニューを動的に生成する方法
  • Vueはどのようにしてバックグラウンドからデータを取得して動的なメニューリストを生成するのか

<<:  MySQL データ型の最適化の原則

>>:  Tomcat サーバーの設定と Web プロジェクトの公開に関する IDEA グラフィック チュートリアル

推薦する

MySQL テーブルの追加、削除、変更、クエリの基本チュートリアル

1. 作成する [テーブル名] (フィールド1、フィールド2、...) 値 (値1、値2、...) ...

HTML でフロートをクリアする 2 つの方法

1. クリアフローティング法1前の親要素の高さを設定します。注: エンタープライズ開発では、可能であ...

開発効率を向上させる 20 の JavaScript ヒント

目次1. 配列を宣言して初期化する2. 合計、最小値、最大値を計算する3. 文字列、数値、オブジェク...

Ubuntu 18.04の下のディレクトリにディスクをマウントします

導入この記事では、Ubuntu 18.04 デスクトップ システムでディスクを目的のディレクトリにマ...

Day.js をベースにした JavaScript での日付処理のよりエレガントな方法

目次day.js を使用する理由モーメントデイ.js day.js がなければどうなるでしょうか? ...

NestJsはMongooseを使用してMongoDBを操作する

最近、NestJs フレームワークを学び始めました。学習コストは他のフレームワークよりもはるかに高く...

MySQL 5.7.17 のインストールと使用方法のグラフィックチュートリアル

MySQL は、スウェーデンの会社 MySQL AB によって開発され、現在は Oracle が所有...

初心者がHTMLタグを学ぶ(2)

初心者は、いくつかの HTML タグを理解することで HTML を学習できます。この入門書は、初心者...

HTML文書の基本構造(Webページ作成の基礎知識)

HTMLの動作原理: 1. ローカル操作: ブラウザでhtmlファイルを開く2. リモートアクセス...

HTML でよく使用されるエスケープ文字の概要

HTML でよく使用されるエスケープ文字をまとめると次のようになります。 &nbsp; 改行...

jsBridgeの動作メカニズムを1つの記事で学ぶ

目次js 呼び出しメソッドアンドロイド1.jsはネイティブを呼び出す2. ネイティブコールjs iO...

Vue Element フロントエンドアプリケーション開発 テーブルリスト表示

1. リストクエリインターフェースの効果コード処理ロジックを紹介する前に、まずは感覚的に理解し、レン...

Linux環境でタイムゾーンを設定できない問題を解決

Linuxでタイムゾーンを変更する場合、常に変更することはできませんAsia/Shanghai に変...

MySQL 8.0.18 のさまざまなバージョンのインストールとインストール中に発生した問題 (要点の要約)

概要: MYSQLの問題解決記録:どのようなインストール方法 (rpm、gz、gz.xz) を使用す...

Vue3.0 異なる解像度のコンピュータの適応操作

まず依存関係をインストールする必要があります npm i lib-flexible-computer...