Vueは動的ルーティングの詳細を実装します

Vueは動的ルーティングの詳細を実装します

主流の実装方法:

2つの方法の利点について簡単に説明しましょう。結局、やったことがないと、いくら言っても理解できません。やはりコードを見なければなりません。

フロントエンド制御

  • バックエンドのヘルプはなく、ルーティングテーブルはフロントエンドで管理されます
  • ロジックは比較的シンプルで使いやすい

バックエンド制御

  • 比較的安全
  • ルーティングテーブルはデータベースで管理されます

1. フロントエンド制御

アイデア:ルーティング設定では、 meta属性を通じて権限に関連するフィールドを拡張し、ルーティングガードでは、この権限識別子を判断することで、ルートとページジャンプの動的な増加を実現します。たとえば、ロールを制御するためのroleフィールドを追加します。

具体的な計画:

1. ログインしたユーザーのアカウントに基づいてフロントエンドユーザーのロールを返す

2. フロントエンドは、ユーザーの役割に応じてルーティングテーブルのmeta.roleを一致させます。

3. 一致したルートをアクセス可能にする

コアコードロジック

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からデータを取得できる

コアコードは、サイドバーをレンダリングするためにrouterから利用可能なルーティングオブジェクトを取得することです。フロントエンドの動的ロードでも、バックエンドルーティングの動的ロードでも、このコードは同じです。

<!-- 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. バックエンド制御ルーティング

バックエンド制御の一般的な考え方は、ルーティング構成がデータベース テーブルに配置され、ユーザーが正常にログインすると、ロールの権限に応じて権限付きのメニューがフロントエンドに渡されるというものです。フロントエンドは、それをページ ルーティングが認識できる構造にフォーマットし、ページ メニューにレンダリングします。

  • ユーザーがログインすると、バックエンドはユーザーの役割に基づいてアクセス可能なルーティングデータを直接生成します。これはデータであることに注意してください。
  • フロントエンドは、バックエンドから返されたルーティングデータを必要なルーティング構造に変換します。

具体的なロジック:

  • loginや 404 など、一部の静的ルートのみが router.js に配置されます。
  • データ構造を整理し、テーブルに保存する
  • バックエンドからルーティングデータを取得し、データをアクセス可能なルートに変換するデータ変換メソッドを記述します。
  • また、 vuex状態を維持し、変換されたルートをvuexに保存します。
  • サイドバーはレンダリングのためにルートからデータも取得します

フロントエンド制御とバックエンド制御の背後にあるプロセスはほぼ同じであるため、ここではフロントエンドの異なるプロセスのみを見ていきます。

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 を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • vue-router の動的ルーティングとは何かを説明します
  • Vue Routerは動的ルーティングと一般的な問題と解決策を実装します
  • Vue ルーターの基本的な使い方(動的ルーティング、ネストルーティング)の総合分析
  • vueRouter - マッチャーはルーティング方法を動的に増減します

<<:  HTML フォーム_PowerNode Java アカデミー

>>:  Sysbench の MySQL ベンチマーク プロセスの分析

推薦する

マークアップ言語 - アンカー

前: マークアップ言語 - フレーズ要素 オリジナルソース 第 7 章 アンカーHTML のリンクの...

CSS3はマスク連打機能を実現する

最近Bステーションでスマートアンチブロッキング弾幕と呼ばれる弾幕エフェクトを見ました。これは伝説のマ...

Linux で Multitail コマンドを使用するチュートリアル

MultiTail は、tail コマンド機能と同様に、複数のドキュメントを同時に監視するために使用...

Ajax の JavaScript ソリューションにおける parsererror エラー ケースの詳細な説明

ajax の parsererror エラー (バックグラウンドからフロントエンドに送信される js...

uniapp アプレットでウォーターフォール フロー レイアウトを実装するためのアイデアとコード

1. はじめに今、ウォーターフォールフローについて書くことは、古い内容の焼き直しと見なされますか?気...

グリーンスタイルのウェブデザイン作品18点の最新コレクション

トイ・ストーリー3 オンラインマーケティングウェブサイトゼンモバイル鉄から鉄へスプラウトファンドバー...

よく使われるCSSカプセル化方法の概要

1. pc-reset PCスタイルの初期化 /* 正規化.css */ html{ 行の高さ: 1...

LinuxシステムにおけるMySQLの一般的な操作コマンド

仕える: # chkconfig --list すべてのシステムサービスを一覧表示する# chkco...

非ルートユーザーを使用してDockerコンテナでスクリプト操作を実行する

アプリケーションをコンテナ化した後、Docker コンテナを起動すると、デフォルトで root ユー...

Tomcatでcatalina.batがUTF-8に設定されている場合、コンソールに文字化けした文字が表示されます

1. catalina.bat は UTF-8 に設定する必要があります。UTF-8 に設定しないと...

フロントエンドとバックエンドを分離した nginx 構成を展開するための完全な手順

序文決まり文句です。ここでは、フロントエンドとバックエンドの分離についての私の理解についてお話ししま...

Linux の traceroute コマンドの使用方法の詳細な説明

Traceroute を使用すると、情報がコンピュータからインターネットの反対側のホストまでたどるパ...

Vueドロップダウンメニューのコンポーネント開発の詳細説明

この記事の例では、Vueドロップダウンメニューのコンポーネント開発の具体的なコードを参考までに共有し...

mysql5.7.18.zip インストール不要版設定チュートリアル(Windows)

これは私が以前使用した mysql5.7.18.zip のインストール チュートリアルです。まずこれ...

Webデザインと制作のテスト問題と参考回答

<br />Web デザインと制作テスト パート I 多肢選択問題 1. 単一選択問題 ...