Help us understand the problem. What is going on with this article?

nuxt.jsのviewでパスパラメータを使いたいけど、ドキュメント読んでもよくわからなかった

More than 1 year has passed since last update.

GWにはいってから、nuxt.jsをいじりはじめたのだけれど、パスパラメータをviewで表示しようとしたらハマった。

(動的なルーティングを生成するところまでは、ドキュメント読めばわかるのだけれど)

結論

正規

@ospy さん、コメントありがとうございます

参照: https://router.vuejs.org/ja/essentials/dynamic-matching.html

<template>
  <h2>{{ $route.params.id }}</h2>
</template>

<script>
export default {};
</script>

最初にたどり着いた結論

スタンダードなやりかたではないので
こちらでもできなくないぐらいに捉えてください

どうやらこうらしい。
script上では params で参照できるけど、それ以外だと使えない

_id.vue
<template>
  <h2>{{ p.id }}</h2>
</template>

<script>
export default {
  validate({params}) {
    return /^[0-9a-z]+$/.test(params.id)
  },
  asyncData ({ params }) {
    return { p: params }
  }
};
</script>

検証

最初はこう書いた

_id.vue
<template>
  <h2>{{ params.id }}</h2>
</template>

<script>
export default {
  validate({params}) {
    return /^[0-9a-z]+$/.test(params.id)
  }
};
</script>

ドキュメント読んでいたらparamsにパスパラメータが格納されることが理解でき、scriptで普通に呼べていたので、templateで普通に使えるものと思っていたら、見事にエラーになった。

Property or method "params" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

ふむなるほど。わからん。
参照しろといわれたドキュメントを読んで見る。

--- 以下、ドキュメント転記

Vue は動的に新しいルートレベルのリアクティブなプロパティを追加することはできませんので、前もってインスタンス全てのルートレベルのリアクティブな data を宣言して初期化する必要があります。空の値でもかまいません:

var vm = new Vue({
  data: {
    // 空の値として message を宣言する
    message: ''
  },
  template: '<div>{{ message }}</div>'
})
// 後で、`message` を追加する
vm.message = 'Hello!'

data オプションで message を宣言していないと、Vue は render ファンクションが存在しないプロパティにアクセスしようとしていることを警告します。

この制限の背後には技術的な理由があります。それは依存性追跡システムにおけるエッジケースのクラスを排除し、 また Vue インスタンスと型チェックシステムとの親和性を高めます。しかし重要な考慮事項はコードの保守性にあります。data オブジェクトはコンポーネント状態のスキーマのようなものです。前もって全てのリアクティブなプロパティを宣言することで、後から見直したり別の開発者が読んだりしたときにコンポーネントのコードを簡単に理解することができます。

--- 以上、ドキュメント転記

paramsnuxt.jsで管理されているところで使えるだけなので、 export defaultのなかだったら、{params}で参照できるだけで、vueファイル使っているところでプリセットされてるとかそんなわけではないらしい。

ためしに下記のように、export defaultのそとで参照するようにしてみたら見事にReferenceErrorが出た。

_id.vue
<template>
  <h2>{{ params.id }}</h2>
</template>

<script>
console.log(params)
export default {
  validate({params}) {
    return /^[0-9a-z]+$/.test(params.id)
  }
};
</script>

他の人はどう書いてるのか見てみた。

参考にしたページ: https://html5experts.jp/potato4d/24346/

真似して、試してみた。
うごいた。なるほど、asyncDataなどで生成したものは使える。

_id.vue
<template>
  <h2>{{ user.id }}</h2>
</template>

<script>
import axios from 'axios'

export default {
  validate({params}) {
    return /^[0-9a-z]+$/.test(params.id)
  },
  async asyncData ({ params }) {
    const { data: user } = await axios.get(`https://api.github.com/users/${params.id}`)
    return {
      user
    }
  }
};
</script>

ちなみに、これもうごかない

_id.vue
<template>
  <h2>{{ window.navigator.userAgent }}</h2>
</template>

<script>
import axios from 'axios'

export default {
  validate({params}) {
    return /^[0-9a-z]+$/.test(params.id)
  }
};
</script>

グローバルな変数も宣言しないと動かない

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした