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 データをリアルタイムで同期する方法

推薦する

Vue で pdfjs を使用して PDF ファイルをプレビューする方法

目次序文考えるライブラリディレクトリの解析とダウンロード使い方ファイルの場所実際の通話質問要約する序...

CentOS 7 での Nginx ログタイミング分割の実装手順の詳細説明

1. 分割スクリプト (splitNginxLog.sh) を作成します。 * この例では、ログ分割...

あるテーブルからバッチデータをクエリし、それを別のテーブルに挿入する MySQL の完全な例

事前に言っておくNodejs はデータベースを非同期操作として読み取るため、データベースがデータを読...

Dockerはローカルイメージをパッケージ化し、他のマシンに復元します

1. docker imagesを使用して、このマシン上のすべてのイメージファイルを表示します。 2...

React の国際化 react-intl の使用

React で国際化を実現するにはどうすればよいでしょうか? react-intlプラグインは、Re...

Mysqlは日付範囲の抽出方法を指定します

データベースを操作する過程では、いくつかの指標を日付別にまとめたり、一定期間内の合計金額をカウントし...

macOS での MySQL 8.0.17 のインストールと簡単な設定チュートリアル

私が書いた内容が理解できない場合は、インターネット上に理解できるチュートリアルがない可能性があります...

WeChatアプレットでSVGアイコンを使用する方法

SVG は、さまざまな利点があるため、近年広く使用されています。残念ながら、WeChat ミニプログ...

Linux での MySQL 5.6.24 (バ​​イナリ) 自動インストール スクリプト

この記事では、Linux環境でのmysql5.6.24自動インストールスクリプトコードを参考までに共...

WeChatアプレットがSMS認証コード送信のカウントダウンを実装

この記事では、WeChatアプレットがSMS認証コードのカウントダウンを送信するための具体的なコード...

JavaScriptのイベントループの仕組みの分析

目次序文: 1. イベント ループとタスク キューの理由: 2. イベントループメカニズム: 3. ...

マージンのマージの問題を解決する

1. 兄弟要素の余白を結合する効果は次のようになります: (2 つの間の間隔は 150 ピクセルでは...

.Net Core を使用して数千万のデータを MySQL にインポートする手順

目次事前準備実施方法: 1. 単一のデータを挿入する2. マージデータ挿入3. MySqlBulkL...

Tomcat サーバーの応答が遅い場合の解決策

1. 分析的思考1. 機械自身の理由を排除する2. サーバーパフォーマンス分析3. プロジェクト自体...

Windows 10 に TomCat をインストールするチュートリアル図

WindowsにTomCatをインストールするこの記事では、WindowsプラットフォームにTomC...