Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Nuxt × Vue Router の力を最大限に引き出す機能を紹介

ytr0903
October 19, 2024

Nuxt × Vue Router の力を最大限に引き出す機能を紹介

2024.10.19 に行われた Vue Fes Japan 2024 に登壇した際のスライドです。

https://vuefes.jp/2024/sessions/ykoizumi0903/

ytr0903

October 19, 2024
Tweet

Other Decks in Technology

Transcript

  1. Nuxt × Vue Router の力を Nuxt × Vue Router の力を

    最大限に引き出す機能を紹介 最大限に引き出す機能を紹介 Yutaro Koizumi 2024-10-19 @ Vue Fes Japan 2024
  2. 自己紹介:Yutaro Koizumi (Twitter:@ykoizumi0903) 所属:株式会社アンドパッド(ANDPAD) 工事現場の見積・予算などを作成・確認する「原価管理」 (Nuxt) 承認フローを一元管理する「資料承認」 (Nuxt / Next.js

    併用)などを担当 ※興味のある方はぜひスポンサーブースまでお越しください Zenn や ANDPAD TECH BLOG で記事を書いています 以下は個人的に気に入っているオススメ記事です 祝・正式リリース!5つのテーマで理解する Nuxt3 の魅力 UnJS にどんなツールがあるのか、上位30件すべて紹介してみた(前編) 新規プロダクトの開発に Nuxt 3 を採用して良かったこと Writable Computed を活用して読みやすいVueコードを書くためのTips Vue Fes Japan 2024 開催直前! ykoizumi0903 が語る Vue 推しの理由
  3. 前置き:このテーマを選んだ理由 Nuxt のルーティング周りのキャッチアップは意外と難しい Nuxt と Vue Router の管理が違うので、片方のドキュメントを読んでも全ての情報が掴めない Vue におけるメタフレームワークの比較対象が少ないので、注目されにくい

    React の場合、Next.js、Remix、Astro、Gatsby それぞれの特徴を比べられる Vue 2 の頃からある機能も多く、「Vue 3・Nuxt 3 の新機能」ではないので、紹介される機会が少ない => Nuxt × Vue Router でできることをさわりだけでも紹介することで、   「そういえばこれもできたような…」と頭の片隅に置いておいてもらいたい
  4. Contents 1. Dynamic Routes 2. Catch-All Route 3. Route Groups

    (v3.13~) 4. Nested Routes 5. Typed Pages (v3.5~) 6. Routes’ Matching Syntax 7. Path Ranker (Vue Router Path Parser) ※Route Group 以外は Nuxt ではない Vue Router 単体でも使える機能ですが、 説明を簡略化するため、Nuxt 3 での利用を前提として説明します
  5. Dynamic Routes pages 内のファイル名やディレクトリ名を [] で囲むことで、動的なルートを作成できる https://nuxt.com/docs/guide/directory-structure/pages#dynamic-routes /users/[user_id]/posts/[post_id].vue のように書くことで、ブラケット部分が任意の文字列にマ ッチする

    ファイル名の一部のみをブラケットで囲むことで、部分的に動的なルートになる /pages/user-[id].vue など [[]] と二重に囲むことで、そのパスが省略可能になる /user/[[id]].vue は、 /user/ と /user/1 の両方にマッチする
  6. Route Groups (v3.13~) ディレクトリ名を () で囲むことで、URLに含まれないセグメントを作成できる https://nuxt.com/docs/guide/directory-structure/pages#route-groups /pages/(backstage)/dashboard.vue が /dashboard/

    にマッチする (丸括弧内はURL上は無視される) pages ディレクトリを綺麗に整理できる 理論上は同じルートに一致するページコンポーネントを無数に作れてしまうが、避けた方が良い -| pages/ ---| (backstage)/ -----| dashboard.vue ---| (portal)/ -----| login.vue
  7. Nested Routes ディレクトリと同じ名前の Vue ファイルを作成することで、ページコンポーネントを多重化できる https://nuxt.com/docs/guide/directory-structure/pages#nested-routes 共通部分の layout、ページごとの pages の二層だけでな

    く、URLのパスに一致させる形で多層化できる 動的ルートと組み合わせることも可能(ファイル名とディ レクトリ名をブラケット付きで揃える) Route Groups とは組み合わせられない Tips: ページコンポーネント内で子ページを表示する位置は <Slot /> ではなく <NuxtPage /> タグで指定します -| pages/ ---| index.vue ---| red.vue ---| red/ -----| blue.vue -----| blue/ -------| green.vue
  8. ちなみに…… ここまで紹介した機能(Dynamic Routes, Catch-All Route, Route Groups, Nested Routes)は、 React

    フレームワークである Next.js や Remix もほぼ同様の機能を備えている → 実践的な使い方・考え方については Next.js や Remix のドキュメントや記事を参考にするのもオススメで す Routing: Dynamic Routes | Next.js Routing: Route Groups | Next.js Route Configuration | Remix 例:Next.js 公式ドキュメントによる Nested Routes 概念のわかりやすい図
  9. Typed Pages (v3.5~) Vue Router のページ遷移や動的パラメータの型情報を取得する https://nuxt.com/blog/v3-5#fully-typed-pages <NuxtLink to="path" />

    や useRouter().push('path') などで遷移先を指定する際に、存在する パスを補完してくれる 存在しないページを指定するとタイプエラーになる 動的パスの場合も部分的な補完を受けられる(下画像の :filter() の部分)
  10. Typed Pages (v3.5~) Vue Router のページ遷移や動的パラメータの型情報を取得する https://nuxt.com/blog/v3-5#fully-typed-pages useRoute() の場合は引数にパスを指定することで、動的パラメータなどの型情報を取得できる 例:

    /pages/[user_id]/posts/[post_id].vue というページコンポーネントの場合 useRoute('user_id-posts-post_id') と引数を指定することで、paramsでは user_id と post_id のみにアクセスできる useRoute() は自動で推論されないので、自分で適切なコンテキストを与える必要がある composable や components など、ページコンポーネント外で使っている場合は、あえて引数を渡 さないことで型エラーを回避できる
  11. Typed Pages (v3.5~) Vue Router のページ遷移や動的パラメータの型情報を取得する https://nuxt.com/blog/v3-5#fully-typed-pages Nuxt Config で設定しないと有効化されない

    Nuxt 3.5 以上が必要 Nuxt 以外で利用する場合は → posva/unplugin-vue-router 関連記事: export default defineNuxtConfig({ experimental: { typedPages: true } })
  12. Routes’ Matching Syntax ファイルベースルーティングでは表現しきれない、より柔軟なルーティングを実現する https://nuxt.com/docs/api/utils/define-page-meta#using-a-custom-regular-expression 使い方①ページコンポーネントに definePageMeta() を記述する postId が数字である場合のみマッチする

    /1-new/ にはマッチするが、 /id-new/ にはマッチしなくなる path を上書きするので、ファイル名に基づくルーティングは無視される ファイル名やディレクトリが無関係な場所にあっても関係ない ただし、Nested Routes の影響は受ける 上記のファイルを /pages/red/blue/[postId]-[postSlug].vue に配置した時に、 /pages/red.vue や /pages/red/blue.vue が存在すればネストされたルートとして認識される 影響を受けたくなければ別の場所に移動すれば良いだけなので、便利な場面の方が多いと思います // pages/[postId]-[postSlug].vue definePageMeta({ path: '/:postId(\\d+)-:postSlug' })
  13. Routes’ Matching Syntax ファイルベースルーティングでは表現しきれない、より柔軟なルーティングを実現する https://nuxt.com/docs/api/utils/define-page-meta#using-a-custom-regular-expression 使い方② nuxt.config.ts の pages:extend hook

    を使う definePageMeta() と異なりルートを追加しているので、ファイル名に基づく元のルートも有効 上記の例であれば、 /1-new/ と /red/blue/id-new/ の両方にマッチする pages/ 以外に置いたファイルにマッチさせたり、複数のパスを同じページにマッチさせたりできる さらに素の Vue Router に近い設定方法なので、Vue Router 公式ドキュメントが参考になります export default defineNuxtConfig({ hooks: { 'pages:extend'(routes) { routes.push({ path: '/:postId(\\d+)-:postSlug' file: '~/pages/red/blue/[postId]-[postSlug].vue', }) } } })
  14. Routes’ Matching Syntax ファイルベースルーティングでは表現しきれない、より柔軟なルーティングを実現する https://nuxt.com/docs/api/utils/define-page-meta#using-a-custom-regular-expression Typed Pages との組み合わせも可能 definePageMeta() で指定した動的パラメータも正しく型推論・補完される(string

    型) useRoute() に渡す引数は、 definePageMeta() ではファイル名、 pages:extend では path 文字列 がデフォルトで使われる(こちらも自動で推論されます) name プロパティを指定すると、好きな名前に上書きすることもできる
  15. Path Ranker (Vue Router Path Parser) ルーティングにどのパスがマッチするかを検証する公式ツール https://paths.esm.dev/ pages/ ディレクトリ内に配置している、自分で正規表現を書いていないパスは?

    Nuxt が内部で正規表現に変換している どう変換されているかは /.nuxt/types/typed-router.d.ts を開くと確認できる( typedPages を有効にしている場合のみ) /** * Route name map generated by unplugin-vue-router */ export interface RouteNamedMap { 'index': RouteRecordInfo<'index', '/:page_route(page)?/:page(d+)?/', { page_route?: ParamValueZeroOrOne<true>, page?: P 'category-slug': RouteRecordInfo<'category-slug', '/category/:slug/page/:page(\d+)', { slug: ParamValue<true>, page: Pa 'date-dates': RouteRecordInfo<'date-dates', '/date/:dates(.*)*', { dates?: ParamValueZeroOrMore<true> }, { dates?: Para 'red': RouteRecordInfo<'red', '/red', Record<never, never>, Record<never, never>>, 'red-blue': RouteRecordInfo<'red-blue', '/red/blue', Record<never, never>, Record<never, never>>, 'my-favorite-name': RouteRecordInfo<'my-favorite-name', '/:postId(\d+)-:postSlug()?', { postId: ParamValue<true>, postS 'red-blue-green': RouteRecordInfo<'red-blue-green', '/red/blue/green', Record<never, never>, Record<never, never>>, }
  16. まとめ Vue Router と Nuxt のルーティングは、標準機能だけで細かいところまでカバーしている強力なツールで す 今回紹介した以外にも、様々な機能や利用例があるので、ぜひ目を通してみてください pages/ ·

    Nuxt Directory Structure Getting Started | Vue Router posva/unplugin-vue-router: Next Generation file based typed routing for Vue Router 実際に触ってみた方がわかりやすいので、まずは試してみるのがオススメです 迷ったら typedPages は有効にしましょう! とりあえずオンにすれば恩恵を受けられる機会は多いと思います