主流の実装方法: 2つの方法の利点について簡単に説明しましょう。結局、やったことがないと、いくら言っても理解できません。やはりコードを見なければなりません。 フロントエンド制御
バックエンド制御
1. フロントエンド制御アイデア:ルーティング設定では、 具体的な計画:
コアコードロジック 1. router.js ファイル内 (router.js にそれぞれ静的ルーティングと動的ルーティングを記述します)'vue' から Vue をインポートします 'vue-router' から Router をインポートします。 Vue.use(ルーター) '@/layout' からレイアウトをインポートします // constantRoutes 静的ルーティング、主にログインページ、404 ページなど、動的ルーティングは必要ありません export const constantRoutes = [ { パス: '/redirect', コンポーネント: レイアウト、 非表示: true、 子供たち: [ { パス: '/redirect/:path*', コンポーネント: () => import('@/views/redirect/index') } ] }, { パス: '/login', コンポーネント: () => import('@/views/login/index'), 非表示: true }, { パス: '/404', コンポーネント: () => import('@/views/error-page/404'), 非表示: true }, { パス: '/401', コンポーネント: () => import('@/views/error-page/401'), 非表示: true } ] // asyncRoutes 動的ルーティング export const asyncRoutes = [ { パス: '/permission', コンポーネント: レイアウト、 リダイレクト: '/permission/page', 常に表示: true、 名前: '許可'、 メタ: { タイトル: 「許可」、 アイコン: 'ロック'、 // コアコードは割り当てられたロールによって走査され、表示するかどうかを決定できます // これは管理者と編集者の 2 つのロールを意味します。このメニューにはロールを表示できます: ['admin', 'editor'] }, 子供たち: [ { パス: 'ページ', コンポーネント: () => import('@/views/permission/page'), 名前: 'PagePermission', メタ: { タイトル: 「ページ権限」 // これは管理者だけがロールを表示できることを意味します: ['admin'] } } ] } ] const createRouter = () => 新しいルーター({ スクロール動作: () => ({ y: 0 }), ルート: 定数ルート }) 定数ルーター = createRouter() // これはルーターをリセットするために使用されます。非常に便利ですが、この数行のコードを見ないでください。export function resetRouter() { 定数 newRouter = createRouter() router.matcher = 新しいRouter.matcher } デフォルトルーターをエクスポートする 2. store/permission.js (vuex で状態を維持し、ロールを割り当てることでメニューの表示を制御する)'@/router' から { asyncRoutes, constantRoutes } をインポートします。 // このメソッドはroute.meta.roleとロールを一致させるために使用されます function hasPermission(roles, route) { ルートメタとルートメタロールの場合{ roles.some(role => route.meta.roles.includes(role)) を返します } それ以外 { 真を返す } } // このメソッドは再帰を使用してルートをトラバースし、権限を持つルートをトラバースします export function filterAsyncRoutes(routes, roles) { 定数res = [] ルート.forEach(ルート => { const tmp = { ...ルート } 権限がある場合(ロール、tmp){ tmp.children の場合 { tmp.children = filterAsyncRoutes(tmp.children, ロール) } res.push(tmp) } }) 戻り値 } 定数状態 = { ルート: [], ルートを追加: [] } const 変異 = { SET_ROUTES: (状態、ルート) => { // この場所は2つの状態を維持します。1つはaddRouters、もう1つはroutesです。 state.addRoutes = ルート state.routes = constantRoutes.concat(routes) } } 定数アクション = { ルートを生成する({コミット}, ロール) { 新しいPromiseを返します(resolve => { アクセスされたルート ロールが含まれている場合('admin') アクセスされたルート = 非同期ルート || [] } それ以外 { // コアコード、ルートと取得したロール(バックグラウンドで取得)をマッチングのために渡します accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) } // 一致した承認済みルートを vuex commit('SET_ROUTES', accessedRoutes) に設定します 解決(アクセスされたルート) }) } } エクスポートデフォルト{ 名前空間: true、 州、 突然変異、 アクション } 3. src/permission.js(新しいルーティング ガード関数を作成します。これは main.js に含めることも、ファイルに抽出することもできます) ここでのコードは主に、どのルートがアクセス可能かをチェックする前にルートジャンプを制御するためのものです。ログイン後にジャンプするロジックをここに記述できます。 // 権限.js router.beforeEach((to, from, next) => { if (store.getters.token) { // トークンがあるかどうか確認する to.path === '/login'の場合{ 次へ({ パス: '/' }); } それ以外 { // 現在のユーザーがすべてのuser_info情報を取得したかどうかを判定します if (store.getters.roles.length === 0) { store.dispatch('GetInfo').then(res => { // 情報を取得する 定数ロール = res.data.role; // 取得したロールをマッチングに渡し、アクセス可能なルートを生成します store.dispatch('GenerateRoutes', { roles }).then(() => { // アクセス可能なルーティング テーブルを動的に追加します (コア コード、これがないと何もできません) ルーターにルートを追加します(store.getters.addRouters) // addRoutes が完了していることを確認するためのハック next({ ...to, replace: true }) }) }).catch(エラー => { コンソールログ(エラー); }); } それ以外 { next() // ユーザーの権限がある場合は、アクセス可能なルートがすべて生成されたことを意味します。アクセス権限がない場合は、自動的に 404 ページに入ります。} } } それ以外 { if (whiteList.indexOf(to.path) !== -1) { // ログイン不要のホワイトリストでは、直接 next() に進みます。 } それ以外 { next('/login'); // それ以外の場合はすべてをログインページにリダイレクトします} } }) 4. サイドバーはレンダリングのためにvuexからデータを取得できるコアコードは、サイドバーをレンダリングするために <!-- layout/components/siderbar.vue --> <el-メニュー :default-active="アクティブメニュー" :collapse="折りたたむ" :background-color="変数.menuBg" :text-color="変数.menuText" :unique-opened="false" :active-text-color="variables.menuアクティブテキスト" :collapse-transition="false" モード="垂直" > // ルートをループし、子コンポーネントにパラメータとして渡します <sidebar-item v-for="route inroutes" :key="route.path" :item="route" :base-path="route.path" /> </el-menu> // 承認されたルートを取得するroutes() { これを返します。$router.options.routes } <!-- layout/components/siderbarItem.vue --> <テンプレートスロット="タイトル"> <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /> </テンプレート> <サイドバー項目 v-for="item.children 内の子" :key="child.path" :is-nest="true" :item="子" :base-path="resolvePath(child.path)" クラス="ネストメニュー" /> 小道具: { // ルートオブジェクト アイテム: タイプ: オブジェクト、 必須: true }, ネスト: { タイプ: ブール値、 デフォルト: false }, ベースパス: { タイプ: 文字列、 デフォルト: '' } } フロントエンドはルーティングを制御し、ロジックは比較的単純です。バックエンドはユーザーの役割を保存するだけで、フロントエンドはユーザーの役割を使用してマッチングを行います。しかし、新しいキャラクターを追加する場合は、そのキャラクターを 1 人ずつ追加する必要があるため、非常に面倒になります。 2. バックエンド制御ルーティングバックエンド制御の一般的な考え方は、ルーティング構成がデータベース テーブルに配置され、ユーザーが正常にログインすると、ロールの権限に応じて権限付きのメニューがフロントエンドに渡されるというものです。フロントエンドは、それをページ ルーティングが認識できる構造にフォーマットし、ページ メニューにレンダリングします。
具体的なロジック:
フロントエンド制御とバックエンド制御の背後にあるプロセスはほぼ同じであるため、ここではフロントエンドの異なるプロセスのみを見ていきます。 1. store/permission.js、vuexでデータを取得するためのリクエストを送信するルートを生成する({コミット},データ){ 新しい Promise を返します ((resolve, reject) => { getRoute(data).then(res => { //取得したデータを変換してvuexに保存します const accessedRouters = arrayToMenu(res.data) アクセスされたルーター.concat([{ パス: '*', リダイレクト: '/404', 非表示: true }]) commit('SET_ROUTERS', アクセスされたルーター) 解決する() }).catch(エラー => { 拒否(エラー) }) }) } 2. データ構造を整理してテーブルに保存する// ページルーティングフォーマット { パス: '/form', コンポーネント: レイアウト、 子供たち: [ { パス: 'インデックス', 名前: 'フォーム'、 コンポーネント: () => import('@/views/form/index'), meta: { title: 'フォーム'、 icon: 'フォーム' } } ] } // ソート後のデータ形式 // 第 1 レベル メニュー // ParentId 0 は第 1 レベル メニューとして使用できます。4 桁の ID を選択するのが最適です。プロジェクトを開発するときにその理由がわかります。 id: 1300 親ID: 0 タイトル: 「メニュー管理」 パス: "/menu" 非表示: false コンポーネント: null 非表示: false 名前:「メニュー」 }, // セカンダリメニュー // parentId が 0 でない場合は、parentId をプライマリメニューの ID と一致させ、一致するものを children にプッシュできます { id: 1307 親ID: 1300 タイトル: 「サブメニュー」 非表示: false パス: "menuItem" コンポーネント: "menu/menuItem" // ローカルファイルアドレスと一致させるには hidden: false 名前: "メニュー項目" } 3. 取得したデータをルーター構造に変換する変換メソッドを記述するエクスポート関数arrayToMenu(配列) { 定数ノード = [] // 最上位ノードを取得します for (let i = 0; i < array.length; i++) { 定数行 = 配列[i] // このexistsメソッドは子が存在するかどうかを判定します。if (!exists(array, row.parentId)) { ノード.push({ path: row.path, // ルート アドレス hidden: row.hidden, // バックエンドが構成されていない場合はすべて true component: Layout, // 通常はファイルのコンポーネントと一致します name: row.name, // ルート名 meta: { title: row.title, icon: row.name }, // タイトルは表示名 id: row.id, // ルート ID リダイレクト: 'noredirect' }) } } const toDo = Array.from(ノード) (toDo.length) の間 { 定数ノード = toDo.shift() // 子ノードを取得します for (let i = 0; i < array.length; i++) { 定数行 = 配列[i] // parentIdが等しい親にプッシュします if (row.parentId === node.id) { 定数子 = { パス: row.path、 名前: 行名、 非表示: row.hidden、 // コアコード。セカンダリルートのコンポーネントはページのコンポーネントと一致する必要があるため: require('@/views/' + row.component + '/index.vue'), メタ: { タイトル: row.title, アイコン: row.name }, id: 行.id } ノードの子の場合{ node.children.push(子) } それ以外 { node.children = [子] } toDo.push(子) } } } ノードを返す } // 子が存在するかどうかをチェックする function exists(rows, parentId) { (i = 0; i < 行数.長さ; i++) の場合 { (rows[i].id === parentId) の場合、true を返す } 偽を返す } これで、Vue の動的ルーティングの実装に関する詳細な記事は終了です。Vue の動的ルーティングの実装に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: HTML フォーム_PowerNode Java アカデミー
>>: Sysbench の MySQL ベンチマーク プロセスの分析
前: マークアップ言語 - フレーズ要素 オリジナルソース 第 7 章 アンカーHTML のリンクの...
最近Bステーションでスマートアンチブロッキング弾幕と呼ばれる弾幕エフェクトを見ました。これは伝説のマ...
MultiTail は、tail コマンド機能と同様に、複数のドキュメントを同時に監視するために使用...
ajax の parsererror エラー (バックグラウンドからフロントエンドに送信される js...
1. はじめに今、ウォーターフォールフローについて書くことは、古い内容の焼き直しと見なされますか?気...
トイ・ストーリー3 オンラインマーケティングウェブサイトゼンモバイル鉄から鉄へスプラウトファンドバー...
1. pc-reset PCスタイルの初期化 /* 正規化.css */ html{ 行の高さ: 1...
仕える: # chkconfig --list すべてのシステムサービスを一覧表示する# chkco...
アプリケーションをコンテナ化した後、Docker コンテナを起動すると、デフォルトで root ユー...
1. catalina.bat は UTF-8 に設定する必要があります。UTF-8 に設定しないと...
序文決まり文句です。ここでは、フロントエンドとバックエンドの分離についての私の理解についてお話ししま...
Traceroute を使用すると、情報がコンピュータからインターネットの反対側のホストまでたどるパ...
この記事の例では、Vueドロップダウンメニューのコンポーネント開発の具体的なコードを参考までに共有し...
これは私が以前使用した mysql5.7.18.zip のインストール チュートリアルです。まずこれ...
<br />Web デザインと制作テスト パート I 多肢選択問題 1. 単一選択問題 ...