# [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 :::