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 ベンチマーク プロセスの分析

推薦する

yum インストールエラーの問題を解決する 保護されたマルチライブラリバージョン

現在、クラウドサーバーに nginx をインストールする際、最初に zlib などの依存ライブラリを...

Docker がデータベースのデプロイに適さない 7 つの理由のまとめ

Docker は過去 2 年間で非常に人気が高まっています。開発者はすべてのアプリケーションとソフト...

Vue 開発者向けの VSCode 拡張機能ベスト 7

適切な VS Code 拡張機能を Visual Studio に追加すると、開発者としての作業がは...

chkconfig および systemctl コマンドを使用して Linux サービスを有効または無効にする方法

これは Linux 管理者にとって重要な (そして素晴らしい) トピックなので、誰もが Linux ...

17 個の JavaScript ワンライナー

目次1. DOMとBOM関連1. 要素にフォーカスがあるかどうかを確認する2. 要素の兄弟ノードをす...

Tomcat メモリ オーバーフロー問題の解決経験

少し前に、製品バージョンをテスト用にテスターに​​提出したのですが、テスト結果はまったく予想外のもの...

iframe が HTML 内のページにジャンプするのを防ぎ、iframe を使用して WeChat Web バージョンをページに埋め込む方法

私は、WinForm と HTML5 を組み合わせた小さなものを作りたいだけなのですが、突然、そこに...

IDEA2021 tomcat10 サーブレットの新しいバージョンの落とし穴

私が学習していたときに使用していたバージョンは比較的新しいものであり、インターネット上のチュートリア...

React+Koa によるファイルアップロードの実装例

目次背景サーバーの依存関係バックエンド構成クロスドメインバックエンド構成の静的リソースアクセスではk...

CSS 疑似要素と疑似クラスの魔法のような使い方についての簡単な説明

CSS は Web ページで非常に重要な役割を果たします。近年の CSS の発展に伴い、疑似要素/疑...

床スクロール効果を実現する js

この記事ではjQueryを使用して、階段のスライド効果を実装し、フロアをスクロールし、フロアボタンを...

HTML シンボルからエンティティへのアルゴリズムのチャレンジ

チャレンジ:文字列内の文字 &、<、>、" (二重引用符)、および &...

HTMLタグの書き方でよくある間違い

注意を払う必要があります。HTML Police がコードを調べて、意味のないタグをすべて見つけ出す...

Windows Server 2008R2 ファイル サーバーを Windows Server 2016 にアップグレードする

ユーザー組織には、ドメインに参加している 2 台の Windows Server 2008 R2 フ...

HTML 縦列表示テキストを使用してテキストを縦列で表示します

コードをコピーコードは次のとおりです。 <span style='display:bl...