1 つの記事で Vue ミドルウェア パイプラインを学ぶ

1 つの記事で Vue ミドルウェア パイプラインを学ぶ

SPA を構築する場合、多くの場合、特定のルートを保護する必要があります。たとえば、認証されたユーザーだけがアクセスできるダッシュボード ルートがあるとします。認証ミドルウェアを使用すると、正当なユーザーだけがアクセスできるようにすることができます。

このチュートリアルでは、Vue-Router[1]を使用してVueアプリケーションのミドルウェアパイプラインを実装する方法を学習します。

ミドルウェア パイプラインとは何ですか?

ミドルウェア パイプラインは、互いに並行して実行されるさまざまなミドルウェアの集まりです。

前の例を続けて、/dashboard/movies に、登録したユーザーだけがアクセスできるようにしたい別のルートがあるとします。ダッシュボード ルートにアクセスするには、認証が必要であることはすでにわかっています。では、認証されサブスクライブされたユーザーだけがアクセスできるようにするには、/dashboard/movies ルートをどのように保護すればよいでしょうか?ミドルウェア パイプラインを使用すると、複数のミドルウェアを連結し、それらを並行して実行できるようになります。

始める

まず、Vue CLI[2]を使用して新しいVueプロジェクトを素早く構築します。

vue は vue-middleware-pipeline を作成します

依存関係をインストールする

プロジェクト ディレクトリが作成され、インストールされたら、新しく作成されたディレクトリに移動し、ターミナルから次のコマンドを実行します。

npm i vue-router vuex

Vue-router[3] — Vue.jsの公式ルーターです

Vuex[4] — Vueの状態管理ライブラリです

コンポーネントの作成

私たちのプログラムは3つの要素から構成されます。

ログイン - このコンポーネントは、まだ認証されていないユーザーに表示されます。

ダッシュボード - このコンポーネントはログインしたユーザーに表示されます。

映画 — ログインしていてアクティブなサブスクリプションを持つユーザーにこのコンポーネントが表示されます。

これらのコンポーネントを作成しましょう。 src/components ディレクトリに移動し、次のファイルを作成します: Dashboard.vue、Login.vue、Movies.vue

次のコードを使用して Login.vue ファイルを編集します。

<テンプレート>
  <div>
    <p>これはログインコンポーネントです</p>
  </div>
</テンプレート>

次のコードを使用して Dashboard.vue ファイルを編集します。

<テンプレート>
  <div>
    <p>これは認証されたユーザー用のダッシュボード コンポーネントです</p>
    <ルータービュー/>
  </div>
</テンプレート>

最後に、Movies.vue ファイルに次のコードを追加します。

<テンプレート>
  <div>
    <p>これは、認証され登録されたユーザー向けの映画コンポーネントです</p>
  </div>
</テンプレート>

ストアを作成する

Vuex に関する限り、ストアはプログラムの状態を保存するための単なるコンテナです。これにより、ユーザーが認証されているかどうかを確認できるだけでなく、ユーザーがサブスクライブされているかどうかも確認できます。

src フォルダーに store.js ファイルを作成し、次のコードを追加します。

'vue' から Vue をインポートします
'vuex' から Vuex をインポートします

Vue.use(Vuex)

デフォルトの新しいVuex.Storeをエクスポートします({
    州: {
        ユーザー: {
            ログイン: false、
            購読済み: false
        }
    },
    ゲッター: {
        認証(状態) {
            state.user を返す
        }
    }
})

ストアには、その状態のユーザー オブジェクトが含まれます。ユーザー オブジェクトには loggedIn プロパティと isSubscribed プロパティが含まれており、ユーザーがログインしていて有効なサブスクリプションを持っているかどうかを判断するのに役立ちます。また、ユーザー オブジェクトを返すためにストア内にゲッターも定義しました。

ルートの定義

ルートを作成する前に、ルートを定義し、ルートにアタッチされる対応するミドルウェアを関連付ける必要があります。

/login は認証されたユーザーを除くすべてのユーザーがアクセスできます。認証されたユーザーがこのルートにアクセスすると、ダッシュボード ルートにリダイレクトされる必要があります。このルートにはゲストミドルウェアが接続されている必要があります。

認証されたユーザーのみが /dashboard にアクセスできます。それ以外の場合、ユーザーはこのルートにアクセスするときに /login ルートにリダイレクトされる必要があります。このルートに認証ミドルウェアを関連付けます。

認証され、登録されたユーザーのみが /dashboard/movies にアクセスできます。このルートは、isSubscribed および auth ミドルウェアによって保護されています。

ルートの作成

次に、src ディレクトリに router フォルダーを作成し、そのフォルダーに router.js ファイルを作成します。次のコードを使用してファイルを編集します。

'vue' から Vue をインポートします
'vue-router' から Router をインポートします。
'../store' からストアをインポートします

'../components/Login' からログインをインポートします
'../components/Dashboard' からダッシュボードをインポートします
'../components/Movies' から Movies をインポートします


Vue.use(ルーター)

const router = 新しいルーター({
    モード: '履歴'、
    ベース: process.env.BASE_URL、
    ルート: [
        {
            パス: '/login',
            名前: 'ログイン',
            コンポーネント: ログイン
        },

        {
            パス: '/dashboard',
            名前: 'ダッシュボード'、
            コンポーネント: ダッシュボード、
            子供たち: [{
                パス: '/dashboard/movies',
                名前: 'dashboard.movi​​es',
                コンポーネント: 映画
            }
        ]、
        }
    ]
})


デフォルトルーターをエクスポートする

ここでは、新しいルーター インスタンスを作成し、いくつかの構成オプションと、以前に定義したすべてのルートを取得するルート プロパティを渡します。これらのルートは現在保護されていないことに注意してください。この問題はすぐに修正されます。

次に、ルートを挿入して Vue インスタンスに保存します。次のコードを使用して src/main.js ファイルを編集します。

'vue' から Vue をインポートします
'./App.vue' からアプリをインポートします。
'./router/router' からルーターをインポートします
'./store' からストアをインポートします

Vue.config.productionTip = false


新しいVue({
  ルーター、
  店、
  レンダリング: h => h(App),
}).$mount('#app')

ミドルウェアの作成

src/router ディレクトリにミドルウェア フォルダーを作成し、そのフォルダーに guest.js、auth.js、および IsSubscribed.js ファイルを作成します。 guest.js ファイルに次のコードを追加します。

エクスポートデフォルト関数ゲスト({ next, store }){
    ストアの認証がログインしている場合
        次を返す({
           名前: 'ダッシュボード'
        })
    }
   
    次を返す()
   }

ゲスト ミドルウェアは、ユーザーが認証されているかどうかを確認します。認証が成功すると、ダッシュボード パスにリダイレクトされます。

次に、次のコードを使用して auth.js ファイルを編集します。

デフォルトの関数 auth ({ next, store }) をエクスポートします。
 (!store.getters.auth.loggedIn)の場合{
     次を返す({
        名前: 'ログイン'
     })
 }

 次を返す()
}

認証ミドルウェアでは、ストアを使用して、ユーザーが現在認証されているかどうかを確認します。ユーザーがすでにログインしているかどうかに応じて、リクエストを続行するか、ログイン ページにリダイレクトします。

次のコードを使用して isSubscribed.js ファイルを編集します。

エクスポートデフォルト関数isSubscribed({ next, store }){
    サブスクライブされている場合
        次を返す({
           名前: 'ダッシュボード'
        })
    }
   
    次を返す()
   }

isSubscribed のミドルウェアは、auth ミドルウェアに似ています。ユーザーが登録しているかどうかを確認するためにストアを使用します。ユーザーがサブスクライブしている場合は、期待されるルートにアクセスできます。そうでない場合は、ダッシュボード ページにリダイレクトされます。

ルートの保護

すべてのミドルウェアが作成されたので、それらを使用してルートを保護しましょう。次のコードを使用して src/router/router.js ファイルを編集します。

'vue' から Vue をインポートします
'vue-router' から Router をインポートします。
'../store' からストアをインポートします

'../components/Login' からログインをインポートします
'../components/Dashboard' からダッシュボードをインポートします
'../components/Movies' から Movies をインポートします

'./middleware/guest' からゲストをインポートします。
'./middleware/auth' から auth をインポートします。
'./middleware/isSubscribed' から isSubscribed をインポートします。

Vue.use(ルーター)

const router = 新しいルーター({
    モード: '履歴'、
    ベース: process.env.BASE_URL、
    ルート: [{
            パス: '/login',
            名前: 'ログイン',
            コンポーネント: ログイン、
            メタ: {
                ミドルウェア:
                    ゲスト
                ]
            }
        },
        {
            パス: '/dashboard',
            名前: 'ダッシュボード'、
            コンポーネント: ダッシュボード、
            メタ: {
                ミドルウェア:
                    認証
                ]
            },
            子供たち: [{
                パス: '/dashboard/movies',
                名前: 'dashboard.movi​​es',
                コンポーネント: 映画、
                メタ: {
                    ミドルウェア:
                        認証、
                        購読済み
                    ]
                }
            }],
        }
    ]
})

デフォルトルーターをエクスポートする

ここでは、すべてのミドルウェアをインポートし、ミドルウェアの配列を含む各ルートのメタ フィールドを定義しました。ミドルウェア配列には、特定のルートに関連付けるすべてのミドルウェアが含まれます。

Vue ルーティング ナビゲーション ガード

ルートを保護するために、Vue Routerが提供するナビゲーションガード[5]を使用します。これらのナビゲーション ガードは、ルートをリダイレクトまたはキャンセルすることでルートを保護します。

ガードのうちの 1 つはグローバル ガードです。これは通常、ルートがトリガーされる前に呼び出されるフックです。グローバル ガードを登録するには、ルーター インスタンスで beforeEach メソッドを定義する必要があります。

const router = 新しい Router({...})
router.beforeEach((to, from, next) => {
 //フックを解決するために必要なロジック
})

beforeEach メソッドは次の 3 つのパラメータを受け取ります。

to: これはアクセスする予定のルートです。

出典: これが現在のルートです。

next: これはフックを呼び出す関数です。

ミドルウェアの実行

beforeEach フックを使用してミドルウェアを実行できます。

const ルーター = 新しいルーター({...})

router.beforeEach((to, from, next) => {
    if (!to.meta.middleware) {
        次を返す()
    }
    const ミドルウェア = to.meta.middleware

    定数コンテキスト = {
        に、
        から、
        次、
        店
    }
    ミドルウェア[0]を返す({
        ...コンテクスト
    })
})

まず、現在処理中のルートにミドルウェア属性を含むメタ フィールドがあるかどうかを確認します。ミドルウェア属性が見つかった場合、それは const 変数に割り当てられます。次に、各ミドルウェアに渡す必要があるすべてのものが含まれるコンテキスト オブジェクトを定義します。次に、ミドルウェア配列の最初のミドルウェアを関数として呼び出し、コンテキスト オブジェクトを渡します。

/dashboard ルートにアクセスしてみると、ログイン ルートにリダイレクトされるはずです。これは、/src/store.js の store.state.user.loggedIn プロパティが false に設定されているためです。 store.state.user.loggedIn プロパティを true に変更すると、/dashboard ルートにアクセスできるようになります。

現在、ミドルウェアは動作していますが、これは私たちが望んでいる動作ではありません。私たちの目標は、特定のパスに対して複数のミドルウェアを実行できるパイプラインを実装することです。

ミドルウェア[0]({ …context} "0") を返す
上記のコード ブロックでは、メタ フィールドのミドルウェア配列から渡された最初のミドルウェアのみを呼び出していることに注意してください。では、配列に含まれる他のミドルウェア (存在する場合) も呼び出されるようにするにはどうすればよいでしょうか?ここでパイプが役に立ちます。

パイプラインを作成する

src/router ディレクトリに変更し、middlewarePipeline.js ファイルを作成します。ファイルに次のコードを追加します。

関数 middlewarePipeline (コンテキスト、ミドルウェア、インデックス) {
    const nextMiddleware = ミドルウェア[インデックス]

    if(!nextミドルウェア){
        コンテキストを返す.next 
    }

    戻り値 () => {
        const nextPipeline = ミドルウェアPipeline(
            コンテキスト、ミドルウェア、インデックス + 1
        )

        nextMiddleware({ ...コンテキスト、次: nextPipeline })

    }
}

デフォルトのミドルウェアパイプラインをエクスポートする

middlewarePipeline には 3 つのパラメータがあります。

context: これは先ほど作成したコンテキスト オブジェクトであり、スタック内の各ミドルウェアに渡すことができます。

middleware: これはルートのメタフィールドで定義されたミドルウェア配列そのものです。

index: これは、ミドルウェア配列内で実行する現在のミドルウェアのインデックスです。

const nextMiddleware = ミドルウェア[インデックス]
if(!nextミドルウェア){
コンテキストを返す.next
}

ここでは、middlewarePipeline 関数に渡されたインデックス内のミドルウェアを単純に抽出しています。インデックスにミドルウェアが見つからない場合は、デフォルトの次のコールバックが返されます。

戻り値 () => {
const nextPipeline = ミドルウェアPipeline(
コンテキスト、ミドルウェア、インデックス + 1
)
nextMiddleware({ ...コンテキスト、次: nextPipeline })
}

コンテキストを渡して nextMiddleware を呼び出し、次に nextPipeline const を呼び出します。 middlewarePipeline 関数は、インデックスを 1 に増やしながら、スタック内で実行する次のミドルウェアを取得するために自身を呼び出す再帰関数であることに注意してください。

すべてをまとめると

middlewarePipeline を使用しましょう。 src/router/router.js ファイルを次のように編集します。

'vue' から Vue をインポートします
'vue-router' から Router をインポートします。
'../store' からストアをインポートします

'../components/Login' からログインをインポートします
'../components/Dashboard' からダッシュボードをインポートします
'../components/Movies' から Movies をインポートします

'./middleware/guest' からゲストをインポートします。
'./middleware/auth' から auth をインポートします。
'./middleware/isSubscribed' から isSubscribed をインポートします。
'./middlewarePipeline' から middlewarePipeline をインポートします。

Vue.use(ルーター)

const router = 新しいルーター({
    モード: '履歴'、
    ベース: process.env.BASE_URL、
    ルート: [{
            パス: '/login',
            名前: 'ログイン',
            コンポーネント: ログイン、
            メタ: {
                ミドルウェア:
                    ゲスト
                ]
            }
        },
        {
            パス: '/dashboard',
            名前: 'ダッシュボード'、
            コンポーネント: ダッシュボード、
            メタ: {
                ミドルウェア:
                    認証
                ]
            },
            子供たち: [{
                パス: '/dashboard/movies',
                名前: 'dashboard.movi​​es',
                コンポーネント: 映画、
                メタ: {
                    ミドルウェア:
                        認証、
                        購読済み
                    ]
                }
            }],
        }
    ]
})

router.beforeEach((to, from, next) => {
    if (!to.meta.middleware) {
        次を返す()
    }
    const ミドルウェア = to.meta.middleware
    定数コンテキスト = {
        に、
        から、
        次、
        店
    }

    ミドルウェア[0]を返す({
        ...コンテクスト、
        次へ: middlewarePipeline(コンテキスト、ミドルウェア、1)
    })
})

デフォルトルーターをエクスポートする

ここでは、スタックに含まれる後続のミドルウェアを実行するために <code> middlewarePipeline <code> を使用します。

ミドルウェア[0]を返す({
...コンテクスト、
次へ: middlewarePipeline(コンテキスト、ミドルウェア、1)
})

最初のミドルウェアが呼び出された後、middlewarePipeline 関数を使用して、スタックに含まれる後続のミドルウェアも、利用できるミドルウェアがなくなるまで呼び出されます。

/dashboard/movies ルートにアクセスすると、/dashboard にリダイレクトされます。これは、ユーザーが現在認証されているものの、有効なサブスクリプションがないためです。ストア内の store.state.user.isSubscribed プロパティを true に設定すると、/dashboard/movies ルートにアクセスできるようになります。

要約する

ミドルウェアは、アプリケーション内のさまざまなルートを保護するのに最適な方法です。これは、複数のミドルウェアを使用して Vue アプリケーション内の単一のルートを保護する非常にシンプルな実装です。

Vue ミドルウェア パイプラインを 1 つの記事で学習するこの記事はこれで終わりです。より関連性の高い Vue ミドルウェア パイプラインのコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

参照

[1] Vueルーター: https://router.vuejs.org/

[2] Vue CLI: https://cli.vuejs.org/

[3] Vueルーター: https://github.com/vuejs/vue-router/

[4] ヴュークス: https://vuex.vuejs.org/

[5] ナビゲーションガード: https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards

<<:  MySQLデータベースが大きすぎる場合にバックアップと復元を行う方法

>>:  MySQLデータベースのQPSとTPSの意味と計算方法

推薦する

JavaScript は詳細なコードで星座クエリ機能を実装します

目次1. タイトル2. コード3. 結果IV. 結論1. タイトルテキスト ボックスに誕生日の値を入...

Mysql マスタースレーブ サービスの実装例を構成する

Mysql マスタースレーブ サービスの実装例を構成する### メインデータベースmy.cnfを構成...

WindowsでMysql5.7.17のインストールと起動に失敗する問題を解決する

マシンに初めて MySQL をインストールします。オペレーティングシステムはwin7ですmysqlの...

MYSQL の 3 つのツリー構造テーブル設計の長所と短所の簡単な分析と共有

目次導入質問設計 1: 隣接リストテーブルデザインSQL の例デザイン 2: パスの列挙テーブルデザ...

MySQLのロック機構の詳細な説明

序文データの一貫性と整合性を確保するために、あらゆるデータベースにはロック メカニズムが備わっていま...

Vue の長いリストをすばやく読み込む方法

目次背景メインコンテンツ1. コンポーネントの比較2. 実装のアイデア3. キーメソッドソースコード...

Linux sshのデフォルトのリモートポート番号を変更する6つの手順

Linux のデフォルトの ssh リモート ポートは 22 です。デフォルトのポートは、悪意のある...

awk でのループの使用

同じコマンドを複数回実行するさまざまな種類のループについて学習しましょう。 awk スクリプトには、...

LinuxデバッガGDBの基本的な使い方の詳細な説明

目次1. 概要2. gdbデバッグ2.1. ブレークポイントを設定する2.1.1. ブレークポイント...

uniappのグローバル変数実装の詳細な説明

序文この記事では、uniapp グローバル変数の実装方法をいくつかまとめています。詳細な知識は、uV...

MySQL テーブル結合クエリでグループ化と重複排除を実装する例

目次ビジネスロジックデータテーブル構造クエリロジックSQL スクリプトスクリプトの説明ビジネスロジッ...

HTML の水平および垂直中央揃えの問題の概要

最近、センタリングの問題に数多く遭遇したので、後で簡単に見つけられるように、時間をかけてそれらを要約...

スクロールバーを非表示にしてコンテンツをスクロールする CSS サンプルコード

序文ページの HTML 構造にネストされたボックスが多数含まれている場合、ページに複数の垂直スクロー...

MySQL 8.0.20でNavicatをインストールして接続する方法と注意すべき点

注意事項1. まず、mysql インストール ディレクトリに次の内容の my.ini ファイルを作成...

21 の MySQL 標準化および最適化のベスト プラクティス!

序文良い習慣はすべて宝物です。この記事は、SQL の後悔の治療法、SQL パフォーマンスの最適化、S...