やりたいこと
routeパラメータを、コンポーネント側で$router.params
を使って取り出すのではなく、propsに代入してもらいコンポーネントはvue-router
に依存しないようにする。
お試しコード
ルート定義
ルート定義する際に、 props: true
を追加してあげます。
これをすることで、コンポーネントのプロパティでrouteパラメータを受け取れるようになります。
const routes = [ { path: '/hello/:message', name: 'hello', component: HelloWorld, props: true } ]
コンポーネント側のコード
routeパラメータを受け取るプロパティを定義してあげるだけですね。
検証用に、created
でプロパティの内容を出力してみます。
import { Component, Prop, Vue } from 'vue-property-decorator'; @Component export default class HelloWorld extends Vue { @Prop() private message!: string; created() { console.log('message', this.message) } }
動かしてみた結果
hello/hoge
にアクセスすると、コンソールにhoge
が出力されているので、プロパティでrouteパラメータが受け取れていることが確認できます。
お試しコード(任意のオブジェクトで受け取る)
propsでrouteパラメータの値をオブジェクトで受け取ってみたいと思います。
コンポーネント側のコード
プロパティの型を、stringからMessage型に変更してみます。 Message型には、idとmessageのプロパティを定義してみます。
import { Component, Prop, Vue } from 'vue-property-decorator'; interface Message { id: number message: string } @Component export default class HelloWorld extends Vue { @Prop() private message!: Message created() { console.log('message', this.message) } }
ナビゲーションのコード
ナビゲーション時に、paramsにコンポーネントが要求するオブジェクトを設定してあげます
<router-link :to="{name: 'hello', params:{message: {id: 999, message: 'メッセージ'}}}">Hello!!</router-link>
動かしてみた結果
コンソールにrouteパラメータが出力出来ているので、オブジェクトでの受け渡しが出来ていることが確認できますね。
Vue-Routerへの依存をなくした場合のメリット
テストを考えた場合、コンポーネントがVue-Routerに依存している場合($router.params
へ依存している場合)、モックを定義してあげないとテストができなくなってしまいます。
$router.params
を使わずにプロパティー経由で受け取った場合、下のテストコードのように、propsData
をセットアップするだけでテストが実行可能となります。
describe('HelloWorld', () => { it('test', () => { const wrapper = shallowMount(HelloWorld, { propsData: { message: { id: 1, message: 'メッセージ' } } }) expect(wrapper.text()).toContain('メッセージ') }) })
$route.params
に依存している場合は、下のコードのようにmocksでデータをセットアップする必要があります。
ちょっとめんどくさいのと、コンポーネント単体だけじゃなくルート定義などを意識したテストコードになるのが嫌ですね。
describe('HelloWorld', () => { it('test', () => { const wrapper = shallowMount(HelloWorld, { mocks: { $route: { params: { message: 'メッセージ' } } } }) expect(wrapper.text()).toContain('メッセージ') }) })