1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

nuxtのDynamic Routingは場合によりパラメータが常に任意になるので必須にするにはvalidateを使う

Last updated at Posted at 2018-10-31

2018.10.31現在。nuxt-2.2.0で確認。

問題:ドキュメント通りでは必須パラメータにならない場合がある

https://nuxtjs.org/guide/routing/#dynamic-routes
Dynamic Routingについてのドキュメントを見ると、パラメータを必須にしたい場合は、pages/_id.vueではなく、pages/_id/index.vueにファイルを配置しろと記述されている。

これはpages直下のルーティングには適用されるが、ディレクトリ掘ると対応されず常に任意になる。
例えばpages/post/_id/index.vueは生成された.nuxt/router.jsを見るとパラメータがid?で任意になっている。(追記参照、post.vueが存在しない場合)

再現手順

$ yarn create nuxt-app testhoge
$ mkdir -p testhoge/pages/post1 && touch testhoge/pages/post1/_id.vue
$ mkdir -p testhoge/pages/post2/_id && touch testhoge/pages/post2/_id/index.vue
pages/post1/_id.vue
<template>
  <div>post1: ... {{ $route.params.id }}</div>
</template>
pages/post2/_id/index.vue
<template>
  <div>post2: ... {{ $route.params.id }}</div>
</template>
$ yarn dev

解決策:対象のコンポーネントで、validateを実装してパラメータを制限する

<template>
  <div>required params.id: ... {{ $route.params.id }}</div>
</template>
<script>
export default {
  validate({ params }) {
    // params.idの存在チェックをしとかないと、正規表現マッチ時にstring変換されてtestを通ってしまう場合がある
    return params.id && /^\w+$/.test(params.id)
  }
}
</script>

validate対応で、pages/post/_id.vuepages/post/_id/index.vueは結局どちらでも同じに動作する。

...

どちらのファイル配置を使うかは、ルーティングをネストするかどうかで変わってくるけど、迷うなら_id/index.vue を使うほうが良さそう。
親コンポーネントを作りたい場合や、親コンポーネントなしで兄弟コンポーネントがある場合にも対応しやすい。

■_id配下に子ページコンポーネントがそもそも無いならどっちでもおk
post/
  └ _id.vue

post/
  └ _id/
    └ index.vue


■_id.vueを親コンポーネントにする場合
post/
  ├ _id.vue (<nuxt-child/>を含む) 
  └ _id/
    ├ index.vue
    └ comment.vue

■親コンポーネントは使わないない
post/
  └ _id/
    ├ index.vue
    └ comment.vue

追記

nuxtのルーティング生成のコードを読んだ限り、そもそも、親コンポーネントの無いディレクトリ区切りは想定されていないっぽい。
https://github.com/nuxt/nuxt.js/blob/39b558f59c0ecb5aa40bf709ca5dff83a151b20b/packages/common/src/utils.js#L213

つまりコンポーネントを入れ子にする場合は

pages/
post/
  └ _id/
    ├ index.vue
    └ comment.vue

ではなく

pages/
post.vue (<nuxt-child/>を含む) 
post/
  └ _id/
    ├ index.vue
    └ comment.vue

と、ディレクトリと同名の親コンポーネントを定義する必要があるようだ。
そうすると、nuxtビルドでパラメータ必須でRouter設定が生成される。

まあ、これで設定可能なのは必須/任意だけで、その他validationは本文中の通りComponent.validateを使わないといけない。

ファイル配置での自動ルーティングはあまり気にせずvalidateでのパラメータチェックを重視するのが良さそう。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?