Vue でユーザー権限に基づいてルートを動的に追加する方法

Vue でユーザー権限に基づいてルートを動的に追加する方法

ユーザーの権限に応じて異なるメニュー ページを表示します。

知識ポイント

ルートガード(事前ガードを使用):ユーザーロールに基づいて追加するルートを決定する
vuex: 動的に追加されたルートを保存する

困難

ルートガードはルートが変更されるたびに呼び出される必要があり、ストア内のデータは更新されるたびにクリアされるため、ストアに追加された動的ルートがあるかどうかを判断する必要があります。
(判定が無いと追加し続けてしまいメモリオーバーフローを起こしてしまいます)

ここに画像の説明を挿入

ロールに基づいてルートを決定し、動的ルートをフィルタリングして、各ルートのロールがログイン時に渡されたロールと一致しているかどうかを判断します。

ここに画像の説明を挿入

<テンプレート>
  <div>
    <el-メニュー
      :default-active="$route.path"
      クラス="el-menu-vertical-demo menu_wrap"
      背景色="#324057"
      テキストカラー="白"
      アクティブテキストカラー="#20a0ff"
      :collapse="折りたたむ"
      ユニークオープン
      ルーター
    >
      <el-サブメニュー
        v-for="$store.state.Routers 内のアイテム"
        :key="アイテムのパス"
        :index="アイテムのパス"
        v-if="!item.hidden"
      >
        <テンプレートスロット="タイトル">
          <i class="el-icon-location"></i>
          <span>{{ item.meta.title }}</span>
        </テンプレート>
        <div v-for="chi in item.children" :key="chi.name">
          <el-menu-item v-if="!chi.hidden" :index="item.path + '/' + chi.path">
            <i class="el-icon-location"></i>{{ chi.meta.title }}
          </el-menu-item>
        </div>
      </el-サブメニュー>
    </el-menu>
  </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  名前: "メニューリスト",
  データ() {
    戻る {
      折りたたみ: false、
    };
  },
  作成された() {
    this.$bus.$on("getColl", (データ) => {
      this.isCollapse = データ;
    });
  },
  メソッド: {

  }
};
</スクリプト>

<スタイルスコープ>
.menu_wrap {
  高さ:100vh;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
  幅: 200ピクセル;
  高さ:100vh;
}
</スタイル>
'vue' から Vue をインポートします
'vue-router' から VueRouter をインポートします。
'../store/index' からストアをインポートします

Vue.use(VueRouter)

const オリジナルプッシュ = VueRouter.prototype.push
VueRouter.prototype.push = 関数push(location) {
  元のPush.call(this, location).catch(err => err) を返します
}

エクスポートconstルート=[
  {
    パス: '/home',
    名前: 'First'、
    コンポーネント: () => import('../views/Index.vue'),
    meta: { title: 'ホーム'},
    子供たち: [
      {
        パス: 'インデックス',
        名前: 'ホーム'、
        コンポーネント: () => import('../views/Home'),
        meta: { title: 'ホーム', roles: ['顧客'] }
      }
    ]
  },
  {
    パス: '/index',
    名前: 'NavigationOne'、
    コンポーネント: () => import('../views/Index.vue'),
    meta: { title: 'ナビゲーション 1'},
    子供たち: [
      {
        パス: '人員',
        名前: '人事',
        コンポーネント: () => import('../views/One/Personnel.vue'),
        meta: { title: '人事', roles: ['顧客'] }
      },
      {
        パス: 'アカウント',
        名前: 'アカウント',
        コンポーネント: () => import('../views/One/Account.vue'),
        meta: { title: 'アカウント', roles: ['顧客'] }
      },
      {
        パス: 'psw',
        名前: 'psw',
        コンポーネント: () => import('../views/One/Password.vue'),
        meta: { title: 'psw', roles: ['顧客'] }
      }
    ]
  },
  {
    パス: '/card',
    名前: 'NavigationTwo',
    コンポーネント: () => import('../views/Index.vue'),
    meta: { title: 'ナビゲーション 2'},
    子供たち: [
      {
        パス: 'アクティビティ',
        名前: 'アクティビティ',
        コンポーネント: () => import('../views/Three/Activity.vue'),
        meta: { title: 'アクティビティ', roles: ['顧客'] }
      },
      {
        パス: 'ソーシャル',
        名前: 'ソーシャル'、
        コンポーネント: () => import('../views/Three/Social.vue'),
        meta: { title: 'ソーシャル', roles: ['顧客'] }
      },
      {
        パス: 'コンテンツ',
        名前: 'コンテンツ',
        コンポーネント: () => import('../views/Three/Content.vue'),
        meta: { title: 'コンテンツ', roles: ['顧客'] }
      }
    ]
  },
  {
    パス: '/two',
    名前: 'NavigationThree',
    コンポーネント: () => import('../views/Index.vue'),
    meta: { title: 'ナビゲーション 3'},
    子供たち: [
      {
        パス: 'インデックス',
        名前: '2'、
        コンポーネント: () => import('../views/Two'),
        meta: { title: '2', roles: ['顧客'] }
      }]
  },
  {
    パス: '/404',
    名前: 'エラー'、
    非表示: true、
    メタ: { タイトル: 'エラー'},
    コンポーネント: () => import('../views/Error')
  }
]

エクスポートconst asyncRouter = [
  //エージェント3 スタッフ2
  {
    パス: '/agent',
    コンポーネント: () => import('../views/Index.vue'),
    名前: 'エージェント'、
    meta: { title: 'エージェント', roles: ['エージェント', 'スタッフ']},
    子供たち: [
      {
        パス: '1'、
        名前: 'agentOne',
        コンポーネント: () => import('@/views/agent/One'),
        meta: { title: 'agentOne', roles: ['エージェント', 'スタッフ'] }
      },
      {
        パス: '2'、
        名前: 'agentTwo',
        コンポーネント: () => import('@/views/agent/Two'),
        meta: { title: 'agentTwo', roles: ['エージェント'] }
      },
      {
        パス: '3'、
        名前: 'agentThree',
        コンポーネント: () => import('@/views/agent/Three'),
        meta: { title: 'agentThree', roles: ['エージェント', 'スタッフ'] }
      }
    ]
  },
  //スタッフ3
  {
    パス: '/staff',
    コンポーネント: () => import('../views/Index.vue'),
    名前: 'スタッフ',
    meta: { title: 'スタッフ', roles: ['スタッフ']},
    子供たち: [
      {
        パス: '1'、
        名前: 'StaffOne'、
        コンポーネント: () => import('@/views/Staff/One'),
        meta: { title: 'StaffOne', roles: ['スタッフ'] }
      },
      {
        パス: '2'、
        名前: 'StaffTwo'、
        コンポーネント: () => import('@/views/Staff/Two'),
        meta: { title: 'StaffTwo', roles: ['スタッフ'] }
      },
      {
        パス: '3'、
        名前: 'StaffThree',
        コンポーネント: () => import('@/views/Staff/Three'),
        meta: { title: 'StaffThree', roles: ['スタッフ'] }
      }
    ]
  },
  { パス: '*'、リダイレクト: '/404'、非表示: true }
]

const ルーター = 新しい VueRouter({
  ルート
})


router.beforeEach((to, from, next) => {
  roles = ['スタッフ'] とします
  if(store.state.Routers.length) {
    コンソールログ('はい')
    次()
  } それ以外 {
    console.log('not')
    store.dispatch('asyncGetRouter', {roles})
    .then(res => {
      ルータ.addRoutes(store.state.addRouters)
    })
    の隣に})
    // next() と next({ ...to }) の違い: next() は next('/XXX') を無限にインターセプトできます}
})

デフォルトルーターをエクスポートする

'vue' から Vue をインポートします
'vuex' から Vuex をインポートします
'./module' からモジュールをインポートします

'../router' から router, {routes, asyncRouter} をインポートします。

関数hasPermission(ルート、ロール) {
  ルートメタとルートメタロールの場合{
    ロールを返します。(ロール => route.meta.roles.indexOf(ロール) >= 0)
  } それ以外 {
    真を返す
  }
  
}

/*
  非同期ルーティング テーブルを再帰的にフィルターして、ユーザー ロールに一致するルートを返します @param asyncRouter 非同期ルーティング @param roles ユーザー ロール*/
関数 filterAsyncRouter(asyncRouter, ロール) {
  filterRouter = asyncRouter.filter(route =>{
    if (hasPermission (ルート、ロール)) {
      ルートの子とルートの子の長さが等しい場合
          ルート.children = filterAsyncRouter(ルート.children、ロール)
      }
      真を返す 
    }
    偽を返す
  })
  フィルタールーターを返す
}

Vue.use(Vuex)

デフォルトの新しいVuex.Storeをエクスポートします({
  州: {
    ルータを追加: [],
    ルーター: []
  },
  突然変異:
    getRouter(状態、ロード) {
      // コンソール.log(paload)
      state.Routers = ルートの連結(paload)
      state.addRouters = paload
      // router.addRoutes(paload)
    }
  },
  アクション: {
    asyncGetRouter({コミット},データ){
      const { ロール } = データ
      新しいPromiseを返します(resolve => {
        addAsyncRouters = filterAsyncRouter(asyncRouter, roles) を追加します。
        コミット('getRouter'、AsyncRoutersを追加)
        解決する()
      })
    }
  }
})

Vue でユーザー権限に応じてルートを動的に追加する詳細な説明については、これで終わりです。Vue の動的ルート追加に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vue は権限制御ルーティングを実装します (vue-router は動的にルーティングを追加します)
  • Vue のルーティングの動的追加とメニューメソッドの生成の例
  • VueはルートaddRoutesを動的に追加し、動的ルートをキャッシュに保存することはできません。
  • vue は addRoutes でルートを動的に追加した後に発生する更新失敗の問題を解決します
  • Vuexは、異なるユーザー権限に応じて異なるルーティングリスト機能を表示します。
  • Vue-Access-Control フロントエンドユーザー権限制御ソリューション

<<:  wgetはウェブサイト全体(サブディレクトリ全体)または特定のディレクトリをダウンロードします

>>:  Maxwell を使用して MySQL データをリアルタイムで同期する方法

推薦する

Tomcat 実行時の JVM エンコーディングの問題を修正

質問:最近、プロジェクトを展開すると文字化けしたデータが出てきました。確認したところ、プロジェクトは...

IDEA は MySQL への接続時にエラーを報告します。サーバーが無効なタイムゾーンを返します。タブに移動して serverTimezone プロパティを設定してください。

これからの道は常に困難で、棘だらけです。歯を食いしばって、乗り越えられると信じてください。さあ、さあ...

IIS7 IIS8 リバースプロキシルールの記述、インストール、構成方法

目的: ステーションAをステーションBのセカンダリディレクトリとして扱うのように: http://w...

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

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

ローカル写真をアップロードする前にプレビューコード例を実装するための HTML5 と jQuery

HTML5 と jQuery はアップロード前にローカル画像のプレビューを実装しており、その効果は...

Linux サーバーで MySQL リモート接続を有効にする方法

序文以前の非MKレコードを再編成するためのMySQLの学習説明する有効になっていない場合、データベー...

HTML <!--...--> コメントタグの役割の詳細な分析

多くのウェブサイトのソースコードを確認すると、多くのコメントが見つかります。特に、ソース文書にコメン...

MySQL マスタースレーブレプリケーションの実践の詳細説明 - GTID ベースのレプリケーション

GTIDベースのレプリケーション導入GTID ベースのレプリケーションは、MySQL 5.6 以降に...

Mysqlの自動増分IDについて知らないことがあるかもしれません

導入: MySQL を使用してテーブルを作成する場合、通常は自動インクリメント フィールド (AUT...

UbuntuにMySQLデータベースをインストールする方法

Ubuntu は、Linux をベースにした無料のオープンソース デスクトップ PC オペレーティン...

Reactの3つの主要属性における状態の使用の詳細な説明

目次クラスコンポーネント機能コンポーネントsetStateの落とし穴React では多くの場所でデー...

MySQLに画像を保存する方法

1 はじめにデータベースを設計する場合、画像や音声ファイルをデータベースに挿入することは避けられませ...

ウェブサイト製品設計の参考となるいくつかの原則

以下の分析は製品設計原則に関するものですが、そのほとんどはウェブサイト製品に基づいているため、ユーザ...

CSS カウンターとコンテンツの概要

コンテンツ プロパティは CSS 2.1 で導入され、:before および :after 疑似要素...

17 個の JavaScript ワンライナー

目次1. DOMとBOM関連1. 要素にフォーカスがあるかどうかを確認する2. 要素の兄弟ノードをす...