【Vue Router】ルートのプロパティの型を変換して取得する

プレーンなVueのプロジェクトでルーティングを行いたい場合、Vue Routerモジュールを使用します。

router.vuejs.org

このモジュールでは、静的なURLはもちろん、動的なURLを扱う事ができます。
動的なURLというのは、例えば次のような使い方です。

動的なURLは、URLの中に動的なプロパティ(上記の例ではユーザーIDやブログ記事ID)を設定します。
上記のような目的のURLの場合、動的なプロパティでは整数を設定する事が多いのではないでしょうか?
Vue Routerでは、(設定次第ですが)プロパティを文字型で扱います。

さて、
今回は取得するプロパティの型を変換して、希望する型で扱う方法について触れます。

環境

Vueに関係するモジュールとバージョンは次の通りです。

モジュール名 バージョン
Vue ^2.6.11
Vue Router ^3.4.3

何故、文字型になるのか

ルートのプロパティのモードをBoolean モードにしている可能性があります。

router.vuejs.org

例えば、ユーザー詳細ページを例にして考えてみます。

次のようなURLで詳細ページを見れるようにするとします。

https://example.com/users/:id

下記のようにpropstrueに設定する事で、簡単にコンポーネントから受け取れるようになります。

// router.js

import Vue from 'vue';
import Router from 'vue-router';
import Users from './view/Users.vue';    // view配下にviewコンポーネント を配置している想定です

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: '/users/:id',
      component: Users,
      props: true
    }
  ]
});

しかし、冒頭でお話ししたように、想定した型を定義する事はできません。

プロパティの型を定義する方法

プロパティの型を設定するには、propsFunction モードで定義する必要があります。

router.vuejs.org

前項の例を元に解説します。
Fuction モードでは、文字通り関数でpropsを指定する事ができます。
route.paramsからidを取得して、整数に変換します。

developer.mozilla.org

変換された値はobject型で返す必要がありますので、変換したidをオブジェクトに入れて返します。

// router.js

import Vue from 'vue';
import Router from 'vue-router';
import Users from './view/Users.vue'; 

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: '/users/:id',
      component: Users,
      props: (route) => {
        // 整数に変換
        const id = Number.parseInt(route.params.id, 10);
        if(Number.isNaN(id)) {
          return {};
        }
        // object型で返す
        return { id };
      }
    }
  ]
});

これで、コンポーネント側でpropsで型を数字型(Number)に設定していても取得する事ができます。

// view/User.vue
//..
<script>
export default {
    props: [
        {
            id: {
                type: Number
            }
        }
    ]
}
</script>

router-viewが複数ある場合

次のようにヘッダーと、メインコンテンツでコンポーネントを分けたい場合があります。

<template>
<div>
    <router-view name="header">
    <router-view>
</div>
</template>

この複数設定する場合は、propsもroute-view毎に設定する必要があります。
次のようにBoolean モードと、Functionモードを混同して設定する事もできます。

// router.js

import Vue from 'vue';
import Router from 'vue-router';
import Users from './view/Users.vue';
import HeaderUsers from './view/HeaderUsers.vue'

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: '/users/:id',
      components: {
        default: Users,              // メインコンテンツ
        header: HeaderUsers   // ヘッダーコンテンツ
      },
      props: {
        // メインコンテンツにはpropsの設定をするので、Fuction モードで設定
        default: (route) => {
          const id = Number.parseInt(route.params.id, 10);
          if(Number.isNaN(id)) {
            return {};
          }
          return { id };
        },
        // ヘッダーにはpropsの設定がいらないためBoolean モードで設定
        header: false
      },
    }
  ]
});

©︎2017-2018 WebSandBag