vue * class component * ネストされたルート で動的にタイトルを変えたい

## 今回の内容
nuxt の [ネストされたルート](https://ja.nuxtjs.org/examples/nested-routes/) を実装した時のことです。
大元でカードを表示し、カード内部のテーブルをネストされたルートとして実装しました。
この時、表示するテーブルによってカードのタイトルを変更した際につまづいたので、共有します。

やりたいことは[こちら](https://qiita.com/jianghan0/items/726b6db7972034435e95) の方に似ているのですが、 class component を使っていたので、少しハマりました。

なお、class component は vue-property-decorator を使って実装しています。vue-property-decorator については、[こちら](https://qiita.com/simochee/items/e5b77af4aa36bd0f32e5)の記事などを参考にしてください。

## ディレクトリ構成
```js
components
  |- organisms
      |- Filter.vue
      |- Card.vue
      |- Table.vue
pages
  |- category.vue
  |- index.vue
  |- category
      |- _largeCategory.vue
      |- list.vue
      |- _largeCategory
          |- _middleCategory.vue
          |- list.vue
          |- _middleCategory
              |- list.vue
```

`/category/list`, `/category/01/list`, `/category/01/02/list` のようなルートが有効になっています。

### category.vue
```js
<template>
  <card :header="title">
    <filter :values="filterValues" />
    <div>
      <nuxt-child />
    </div>
  </card>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import Card from '~/components/organisms/Card';
import Filter from '~/components/organisms/Filter';

@Component({
  layout: 'default',
  components: {
    Card,
    Filter,
  }
})
class CategoryPage extends Vue {
  filterValues = {
    start: (new Date()),
    end: (new Date()),
  };

  // !!!!今回のポイント!!!!
  get title(): string {
    return 'hoge';
  }
}

export default CategoryPage;
</script>
```

**Card のタイトルが `hoge` となっていますが、ここをルートによって変更したいです。**


### category/_largeCategory/list.vue
```js
<template>
  <table
    :data="tableData"
    @click="$router.push(`/category/01/list`)"
  >
    Go to middle category
  </table>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import Table from '~/components/organisms/Table';

@Component({
  layout: 'layout',
  components: {
    Table,
  }
})
class LargeCategoryListPage extends Vue {
  get tableData() {
    // テーブルデータを返す
    return {};
  }
}

export default LargeCategoryListPage;
</script>
```

Table 周りは今回関係ないので、かなり簡略化して書いてます。
`_middleCategory/list.vue`, `_smallCategory/list.vue` も同様に書きます。

### category/_largeCategory.vue
```js
<template>
  <nuxt-child />
</template>
```

これによりネストされたルートが出来上がります。
middle も同様に書きます。

## ひとまず試してみた
ここで `hode` と表示されているタイトルを、ルートによって `大カテゴリー`, `中カテゴリー`など、表示を切り替えていきます。

ひとまず、[上で紹介した記事](https://qiita.com/jianghan0/items/726b6db7972034435e95)を参考にやってみます。

### category.vue
```js
// 前略
class CategoryPage extends Vue {
  filterValues = {
    start: (new Date()),
    end: (new Date()),
  };

  get title(): string {
    const matchedRoute = this.$route.matched.slice(-1)[0];
    const nestedData = matchedRoute.components.default.options.data();
    return nestedData ? nestedData.title : '';
  }
}
```
参考にした記事では head だったが、今回欲しいのは data なので `data()` を実行。


### category/_largeCategory/list.vue
```js
// 前略
class LargeCategoryListPage extends Vue {
  title = '大カテゴリー';

  get tableData() {
    // テーブルデータを返す
    return {};
  }
}
```

data として title を置く。

### 実行結果

```
TypeError: Cannot read property 'props' of undefined
    at LargeCategoryListPage.Component._init (vendors.app.js:63604)
    at LargeCategoryListPage.Vue (commons.app.js:29898)
    at new LargeCategoryListPage (list.js:135)
    at collectDataFromConstructor (vendors.app.js:63622)
    at Object.data (vendors.app.js:63697)
    at VueComponent.get (category.js:1513)
    at Watcher.get (commons.app.js:29296)
    at Watcher.evaluate (commons.app.js:29401)
    at VueComponent.computedGetter [as title] (commons.app.js:29651)
    at Object.get (commons.app.js:26894)
```

class component でなければ取得できたのですが、class component だと、 `data()` の実行でエラーが発生します。

## 解決策

### category.vue
```js
// 前略
class CategoryPage extends Vue {

  get title(): string {
    const matchedRoute = this.$route.matched.slice(-1)[0];
    const nestedData = matchedRoute.components.default;
    return nestedData ? nestedData.title : '';
  }
}
```

### category/_largeCategory/list.vue
```js
// 前略
class LargeCategoryListPage extends Vue {
  public static title = '大カテゴリー';

}
```

title を static にすることで取得できました。

## 改善ポイント
- typescript 入れてると `nestedData に title なんてないよ`って怒られるのをどうにかしたい

## 最後に
以上です！
こう書いた方がいい などあればコメントいただけると嬉しいです！