【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名`と表示させておく。

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

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

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

```
***

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

```vuejs:page/page1.vue
<template>
  <div>
    page1
  </div>
</template>

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

```
```vuejs:page/page2.vue
<template>
  <div>
    page2
  </div>
</template>

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

```
```vuejs:page/page3.vue
<template>
  <div>
    page3
  </div>
</template>

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

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

```vuejs: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](https://gyazo.com/d6be819850fa13b08dec79cd38a5329b/raw)

# layoutsから呼ぶ

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

```javascript:middoleware/layouts.js
export default () => {
  console.log('layouts')
}
```

```vuejs: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](https://gyazo.com/311361a38b58f642ee44154f64fe670b/raw)

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

# nuxt.config.jsから呼ぶ

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

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

```javascript:nuxt.config.js

export default {

//・・・省略

  router: {
    middleware: [
      'config'
    ]
  }

//・・・省略
  
}
```
***
**結果**

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

![スクリーンショット 2020-11-22 14.13.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/ff48bfa6-ea92-7615-7d1f-c0a5df8eadd1.png)

**nuxt.config.js**→**layouts**→**pages**の順で呼ばれるのがわかります。


#contextオブジェクト

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

**context**は様々なデータを含んでいます。詳細は[こちら](https://ja.nuxtjs.org/docs/2.x/internals-glossary/context/)

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

**store**の`state`に`status`を用意し、
初期値を`true`とします。
`mutations`の呼び出しで`true`と`false`を切り替える様にします。

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

export const mutations = {
  changeStatus(state){
    state.status = !state.status;
  }
}
```
***
**pages/page1**に`true`、`false`を切り替えるボタンを用意します。

```vuejs: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**から呼びます。

```javascript: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');
  }
}

```
```javascript:nuxt.config.js
//・・・省略

  router: {
    middleware: [
      'auth'
    ]
  }

//・・・省略
  
}
```
***
**結果**

![demo](https://gyazo.com/595d09057584cda133b3460965274338/raw)
***

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