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

推薦する

ブートストラップテーブルの使い方のまとめ

この記事では、bootstrapテーブルの使い方を参考までに紹介します。具体的な内容は次のとおりです...

レスポンシブ Web デザインが価値のない 5 つの理由

この記事は Tom Ewer の Managewp ブログからのもので、現在人気のレスポンシブ デザ...

自動ロック画面機能を実現するjs

1. 使用シナリオこのような要件があるため、システムが開発されました。ユーザーがデスクトップを離れ...

ES6 配列のコピーおよびフィルメソッド copyWithin() および fill() の具体的な使用法

目次バッチコピー copyWithin()配列を埋めるメソッド fill()指数の計算方法については...

Mysqlはブール型の演算を設定します

Mysqlはブール型を設定します1. Tinyintタイプテストテーブルを作成し、blフィールドをブ...

Baotaパネルを再起動すると、「-ModuleNotFoundError: No module named 'geventwebsocket'」というメッセージが表示されます。

背景:サーバーがFlaskプロジェクトをデプロイし、python3をインストールしたため、再起動時に...

複合主キーと複数列インデックスに遭遇した場合の MySQL 行ロックの詳細な説明

背景今日、他のプロジェクト チームと協力してシス​​テムのストレス テストを実施しているときに、プロ...

Dockerは異常なコンテナ操作を排除する

この初心者は、Docker を学び始めたばかりの頃にこのような問題に遭遇しました。記録しておきます。...

Vue+webrtc (Tencent Cloud) ライブブロードキャスト機能の実装実践

目次1. 生放送効果2. ライブストリーミングを開始する手順2.1 Tencent Web(高速ライ...

js キャンバスはランダムなパーティクル効果を実現します

この記事の例では、参考のためにjsキャンバスランダムパーティクルエフェクトの具体的なコードを共有して...

Vueページジャンプの実装方法

1. this.$router.push() 1. ビュー <テンプレート> <d...

React における同期および非同期 setState の問題のコード分析

React は Facebook の社内プロジェクトとして始まりました。 React の出現は革命的...

MySQLの主キーとユニークキーの重複挿入の解決策の詳細な説明

目次解決: 1. 無視する2. 交換する3. 重複キーの更新についてデータを挿入するときに、重複した...

検証コード干渉を実装する js (静的)

この記事では、検証コード干渉を実装するためのjsの具体的なコードを参考までに共有します。具体的な内容...

Vue3 の ref toRef と toRefs の違いを理解する方法

目次1. 基本1.参照2. 参照3. 参照4. 最適な使い方2. 詳細な1. なぜrefが必要なのか...