# [Nuxt] Nuxt 3 - Middleware
###### tags: `Nuxt`
切換網址時,中間攔截的處理階層,例如:進入頁面前要驗證 cookie、token
有三種:
1. 匿名:直接寫在頁面內的 `definePageMeta()`
2. 具名:寫在 `middleware/` 內,非同步自動載入,在頁面內的 `definePageMeta()` 指定要使用的 middleware
* 檔名若為駝峰式命名,使用時要寫 Kebab case,例:`someMiddleware` 要寫 `some-middleware`
4. 全域:寫在 `middleware/` 內,檔名帶有 `.global`,每次改變路由時都會執行
## 匿名 Anonymous (or inline) route middleware
```javascript
<script setup>
definePageMeta({
middleware: (to, from) => {
console.log('middleware - 匿名: ', { to, from });
},
});
</script>
```
## 具名 Named route middleware
```javascript
// middleware/auth.js
export default defineNuxtRouteMiddleware((to, from) => {
const user = useState('user');
if (!user.value.isAuthorized) {
return abortNavigation();
}
return navigateTo('/account');
});
```
```javascript
<script setup>
definePageMeta({
middleware: ['auth'], // 名稱須和 middleware/ 內的檔名相同
// 也可以寫 middleware: 'auth',
});
</script>
```
## 全域 Global route middleware
```javascript
// middleware/check.global.js
export default defineNuxtRouteMiddleware((to, from) => {
if (to.params.id === '1') {
return abortNavigation();
}
if (to.path !== '/') {
return navigateTo('/');
}
});
```
## Format
* `navigateTo(to, options?)`: 可在 plugins 或 middleware 重定向到指定路由,也可直接進行頁面導航。==使用時記得加 `await` 或`return`==
* to: 重定向的路由
* Type: `RouteLocationRaw | undefined | null`
* Default: `'/'`
* options
* replace?: 是否直接取代目前的 history 紀錄
* Type: `boolean`
* Default: `false`
* redirectCode?: 重定向狀態碼
* Type: `number`
* Default: `302`
* external?: 是否允許導航到外部 URL
* Type: `boolean`
* Default: `false`
* open?: 僅套用在 client 端。可設定 `target`、`windowFeatures`
* Type: `OpenOptions`
* `abortNavigation (err?)`: 終止導航,只能在 middleware 內使用
* err: 錯誤訊息
* Type: `string | Error`
## 執行順序
1. global middleware: 依檔名字母順序
2. definePageMeta() 的 middleware: 依陣列順序
### 情境一
`middleware/` 內有 `a.global.js`、`b.global.js`、`auth.js`
```javascript
// 頁面.vue
<script setup>
definePageMeta({
middleware: [
(to, from) => {
// ...
},
'auth',
],
});
</script>
```
#### 執行順序
1. `a.global.js`
2. `b.global.js`
3. 匿名 middleware
4. 具名 middleware - auth.js
### 情境二
`middleware/` 內有 `01.b.global.js`、`02.a.global.js`、`auth.js`
```javascript
// 頁面.vue
<script setup>
definePageMeta({
middleware: [
'auth',
(to, from) => {
// ...
},
],
});
</script>
```
#### 執行順序
1. `01.b.global.js`
2. `02.a.global.js`
3. 具名 middleware - auth.js
4. 匿名 middleware
## 參考資料
* [middleware/](https://nuxt.com/docs/guide/directory-structure/middleware "middleware/ · Nuxt Directory Structure")
* [navigateTo](https://nuxt.com/docs/api/utils/navigate-to "navigateTo · Nuxt Utils")
* [abortNavigation](https://nuxt.com/docs/api/utils/abort-navigation "abortNavigation · Nuxt Utils")
---
:::info
建立日期:2023-08-30
更新日期:2023-08-31
:::