バックエンドの権限に基づいてナビゲーション メニューを動的に生成する 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 グラフィック チュートリアル

推薦する

Windows システムでの MySQL 8.0.21 インストール チュートリアル (図とテキスト)

インストールの提案: インストールには .exe を使用せず、圧縮パッケージを使用してください。これ...

insert と select を組み合わせて、「データベース内のフィールドの最大値 + 1 を挿入する」メソッドを実装する

この記事はmysqlデータベースです質問 1 表 1 のデータを表 2 にインポートします。表 1 ...

SpringBootをDockerにデプロイし、jarパッケージを置き換える方法の詳細な説明

目次プロジェクトディレクトリDockerファイルファイルの展開画像を生成するコンテナを起動するウェブ...

Zabbix を使用して Oracle データベースを監視する方法の詳細な説明

1. 概要Zabbix は非常に強力で、最も広く使用されているオープンソースの監視ソフトウェアです。...

Centos7でのSambaサーバー構成(実戦)

サンバの概要Samba は、Linux および UNIX システム上で SMB プロトコルを実装する...

mysql5.7 でユーザーの初期パスワードを変更する方法

ユーザーが初めて MySQL データベースをインストールするとき、初期のルート パスワードを変更する...

JavaScript配列の一般的なメソッドの概要

目次1. JavaScriptで配列を作成する方法2. 配列メソッドの概要3. 方法の詳細な説明1....

入力ボックスのコンテンツプロンプトと非表示機能を実装する JavaScript

入力ボックスが小さい場合、内容を入力した後に、入力内容が拡大されたプロンプト ボックスを表示したいこ...

Windows DNS サーバーに「ワームレベル」の脆弱性が露呈、17 年間存在

脆弱性の紹介SigRed の脆弱性はワーム化可能であるため非常に危険です。つまり、ユーザーの介入なし...

MySQL 5.6.37 (zip) ダウンロード インストール 構成 グラフィック チュートリアル

この記事では、MySQL 5.6.37のダウンロード、インストール、設定のチュートリアルを参考までに...

mysql57サービスが突然消えた問題をすぐに解決する

1つ、 G:\MySQL\MySQL Server 5.7\bin> mysqld --ini...

MySQLクエリステートメントの簡単な操作例

この記事では、例を使用して、MySQL クエリ ステートメントの簡単な操作を説明します。ご参考までに...

トップナビゲーションバー機能を実現するCSS+HTML

ナビゲーション バー、固定トップ ナビゲーション バー、およびセカンダリ メニューの実装効果図の実装...

node-media-serverを使用してシンプルなストリーミングメディアサーバーを構築する

node-media-server を使用するプロセスの一部を記録します。この記事の環境はWindo...

Windows10 HomeバージョンにDockerをインストールするときに発生する問題の概要

Docker ダウンロード アドレス: http://get.daocloud.io/#instal...