Help us understand the problem. What is going on with this article?

【Nuxt.js】middleware(ミドルウェア)について【まとめ】

middlewareとは

・ページレンダリングが行われる前に、独自の関数を実行できる。
・ユーザー認証が済んでいない状態で特定のページにアクセスした場合のリダイレクト処理などに使用される。

pagesから呼ぶ

midllewareディレクトリ及びpagesディレクトリ配下に以下のように作成

|--middleware
   |--page1.js
   |--page2.js
   |--page3.js
|--pages
   |--page1.vue
   |--page2.vue
   |--page3.vue

middlewareが呼ばれた際に実行させる関数をexport defaultで返す。

コンソールにmiddleware page名と表示させておく。

middoleware/page1.js
export default () => {
  console.log('middleware page1');
}

middoleware/page2.js
export default () => {
  console.log('middleware page2');
}

middoleware/page3.js
export default () => {
  console.log('middleware page3');
}


各pageではそれぞれのpage名に対応したmiddlewareを呼ぶ。

page/page1.vue
<template>
  <div>
    page1
  </div>
</template>

<script>
export default {
  middleware: [
    ['page1']
  ]
}
</script>

page/page2.vue
<template>
  <div>
    page2
  </div>
</template>

<script>
export default {
  middleware: [
    ['page2']
  ]
}
</script>

page/page3.vue
<template>
  <div>
    page3
  </div>
</template>

<script>
export default {
  middleware: [
    ['page3']
  ]
}
</script>


各pageへのリンクをlayoutsに作っておきます。

layouts/default.vue
<template>
  <div>
    <hr>
    <NuxtLink to="/page1">page1</NuxtLink>
    <NuxtLink to="/page2">page2</NuxtLink>
    <NuxtLink to="/page3">page3</NuxtLink>
    <hr>
    <Nuxt />
  </div>
</template>

結果
demo

layoutsから呼ぶ

middllewareディレクトリ配下にlayouts.jsを追加します。

middoleware/layouts.js
export default () => {
  console.log('layouts')
}
layouts/default.vue
<template>
  <div>
    <hr>
    <NuxtLink to="/page1">page1</NuxtLink>
    <NuxtLink to="/page2">page2</NuxtLink>
    <NuxtLink to="/page3">page3</NuxtLink>
    <hr>
    <Nuxt />
  </div>
</template>

<script>
export default {
  middleware: ['layouts']
}
</script>

結果

demo

layoutsから呼ぶことで全てのページにアクセスした際に共通の処理を実行できます。

nuxt.config.jsから呼ぶ

middllewareディレクトリ配下config.jsを追加します。

middoleware/config.js
export default () => {
  console.log('nuxt.config.js');
}
nuxt.config.js
export default {

//・・・省略

  router: {
    middleware: [
      'config'
    ]
  }

//・・・省略

}

結果

nuxt.config.jsから呼ぶとlayoutsから呼ぶのと同じで全てのページで共通の処理として呼ばれますが、その実行順に注意です。

スクリーンショット 2020-11-22 14.13.45.png

nuxt.config.jslayoutspagesの順で呼ばれるのがわかります。

contextオブジェクト

middlewareは第一引数にcontextオブジェクトを取ります。

contextは様々なデータを含んでいます。詳細はこちら

最後にcontextを使って簡単に認証、リダイレクト処理を作ります。

storestatestatusを用意し、
初期値をtrueとします。
mutationsの呼び出しでtruefalseを切り替える様にします。

store/index.js
export const state = () => ({
  status: true
})

export const mutations = {
  changeStatus(state){
    state.status = !state.status;
  }
}

pages/page1truefalseを切り替えるボタンを用意します。

page/page1.vue
<template>
  <div>
    page1
    <button @click="$store.commit('changeStatus')">{{$store.state.status}}</button>
  </div>
</template>

・ボタン(state.status)がfalseの時にはpage3に入れない。
・ボタン(state.status)がtrueの時にはpage2に入れない。

といった仕様にします。

middllewareディレクトリ配下auth.jsを追加します。
nuxt.config.jsから呼びます。

middoleware/auth.js
export default ({store, route, redirect }) => {
  if (store.state.status && route.path === '/page3') {
    console.log('true時はpage3へ行けません。page1に戻ります。');
    redirect('/page1');
  } else if (!store.state.status && route.path === '/page2') {
    console.log('false時はpage2へ行けません。page1に戻ります。');
    redirect('/page1');
  }
}

nuxt.config.js
//・・・省略

  router: {
    middleware: [
      'auth'
    ]
  }

//・・・省略

}

結果

demo


以上です。
ここまで見て頂きありがとうございました!

higa08
12/16まで毎日投稿します。 ご指摘等、大歓迎です。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away