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

推薦する

MySQL で遅い SQL 文を見つける方法

MySQL で遅い SQL ステートメントを見つけるにはどうすればよいでしょうか?これは、多くの人を...

ウェブサイトにダークモード切り替え機能を持たせるための純粋なCSSフリー実装コード

序文ダーク モードの概念は、 MacOS系統のMojaveに由来し、ユーザーが選択できる 2 つのス...

MYSQL マスタースレーブ レプリケーションの知識ポイントの概要

単一の MYSQL サーバーが現在の Web サイトのトラフィックに対応できない場合の最適化ソリュー...

アプレットにおけるwx.getUserProfileインターフェースの具体的な使用

最近、WeChatミニプログラムは、監査ミニプログラムのwx.loginおよびwx.getUserI...

nginx 設定ファイルで環境変数を使用する方法

序文Nginx はパフォーマンスを重視して設計された HTTP サーバーです。Apache や li...

Vueはマルチタブコンポーネントを実装します

効果を直接確認するために、リロード、左を閉じる、右を閉じる、その他の機能を閉じるなどの右クリック メ...

ローカルで起動したときに Vue プロジェクトがクッキーを保持できない問題を解決する

vueプロジェクトをパッケージ化してサーバーにデプロイし、正常にログインできるが、ローカルで起動する...

nginxリバースプロキシによるセッション障害の問題の解決策

同僚から助けを求められました。バックエンド システムへのログインは成功したものの、システムには正常に...

DockerコンテナのライフサイクルアーキテクチャとVMとの違いについて詳しく説明します。

コンテナのライフサイクルコンテナランタイムのライフサイクルコンテナは、分離特性を持つプロセスのセット...

MyCat を使用して Linux で MySQL マスター/スレーブの読み取り/書き込み分離を実装する方法

目次Linux - MyCat を使用して MySQL マスター スレーブの読み取り書き込み分離を実...

MySQL のロードバランサーとして nginx を使用する方法

注意: nginxのバージョンは1.9以上である必要があります。nginxをコンパイルするときに、-...

MySQL の lru リンク リストの簡単な分析

1. 従来のLRUリンクリストについて簡単に説明するLRU:最も最近使われなかったものLRU リンク...

MySQL データベースのホットスタンバイにおける問題点の分析

以前、MySQL データベースのデュアルマシン ホット スタンバイの設定方法を紹介しました。ご興味の...

簡単な計算機を実装する小さなプログラム

この記事の例では、簡単な計算機を実装するための小さなプログラムの具体的なコードを参考までに共有してい...

W3Cチュートリアル(16):その他のW3Cの活動

このセクションでは、その他の重要かつ興味深い W3C アクティビティの概要を説明します。このセクショ...