Vue.js グローバルな定数管理

VueのSPA開発をしていると、定数で管理しておきたいもの(描画する初期値や、何かの一覧など)が多々出てくると思います。

[mixinは問題を抱えている](https://aloerina01.github.io/blog/2018-12-25-1)、ViewModelにあたるのでできればVuexにも格納したくないと思い、別の方法で考えてみました。

## 別jsファイルで管理し、require/import（モジュールシステム）で活用

### 前提
例えば、APIからの返却が下記として、

```js:response
[
{ id: 1, name: 'Qiita', status: { value: 'active' : label: 'アクティブ' } },
{ id: 2, name: 'Qiitb', status: { value: 'active' : label: 'アクティブ' } },
{ id: 3, name: 'Qiitc', status: { value: 'active' : label: 'アクティブ' } },
]
```

下記のテーブルのように表示したいとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192967/5245707a-b1dd-5402-2f5a-a356f115e01a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192967/e127c0de-7ef0-a448-b56b-085fe5cccee3.png)



### 定数を別jsファイルで管理
まずは、テーブルカラムを定義
consts/hoge/table配下

```js:HogeTableColumnName.js
export default {
 ID: 'id',
 NAME: 'name',
 STATUS: 'status'
}
```

次に、描画用の情報を定義

```js:HogeTableColumnList.js
import HogeTableColumnName from 'HogeTableColumnName'

export default [
 { property: 'HogeTableColumnName.ID', label: 'ID' },
 { property: 'HogeTableColumnName.NAME', label: '名前' },
 { property: 'HogeTableColumnName.STATUS', label: 'ステータス' },
]
```
オブジェクトに対してObject.kesを使用すると順番が確約されないので、配列で管理


### Vueコンポーネント内にて、require/import（モジュールシステム）で活用

```vuejs
<template>
 <table>
  <thead>
   <tr>
    <!-- columnの数だけカラム生成 -->
    <th v-for="column in HogeTableColumnList">
     {{ column.label }}
    </th>
   </tr>
  </thead>
  <tbody>
   <!-- responseの数だけレコード生成 -->
   <tr v-for="res in response">
    <!-- columnの数だけカラム生成 -->
    <td v-for="column in HogeTableColumnList">
     <template v-if="column.propery === HogeTableColumnName.STATUS">
     {{ res[column.property].label }}
     </template>
     <template v-else>
     {{ res[column.property] }}
     </template>
    </td>
   </tr>
  </tbody>
 </table>
</template>
<script>
import HogeTableColumnList from 'path/const/hoge/table/HogeTableColumnList'
import HogeTableColumnName from 'path/const/hoge/table/HogeTableColumnName'

export default {
 computed: {
  // methods内のみであれば不要だが、template内で使用するために必要
　// dataプロパティへの定義も可
  HogeTableColumnList() {
   return HogeTableColumnList
  },
  HogeTableColumnName() {
   return HogeTableColumnName
  }
 }
}
</script>
```
どこまで定数として管理するのか悩みますが、templateがシンプルになりやすく、コンポーネント管理がしやすくなるのではと思っています。

他の定数管理方法は、下記に紹介されていますが、②で `アプローチは、他の開発者と働いたり、大規模なアプリケーションを開発する際に、最も保守性が高いです。` と記載されているので良さそうです。
①[Vue.jsでグローバルな定数をコンポーネントで使いまわせるようにしたい](https://qiita.com/amagurix/items/0f19d04b7771a71b5eaf)
②[Vue.js公式: インスタンスプロパティの追加 / モジュールシステムを使用する場合](https://jp.vuejs.org/v2/cookbook/adding-instance-properties.html#%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88)

（また、テストする際にも使用できそう）

### 応用
#### templateの例外処理をmethodsに移行
```vue
<!-- columnの数だけカラム生成 -->
<template>
 <td v-for="column in HogeTableColumnList">
  <template v-if="column.propery === HogeTableColumnName.STATUS">
  {{ res[column.property].label }}
  </template>
  <template v-else>
  {{ res[column.property] }}
  </template>
 </td>
</template>
```

```vue
<!-- columnの数だけカラム生成 -->
<template>
 <td v-for="column in HogeTableColumnList">
  {{ getColumnValue(res, column.property) }}
 </td>
</template>
<script>
export default {
 methods: {
  getColumnValue(res columnName) {
   if (columnName === this.HogeTableColumnName.STATUS) {
    return res[columnName].label
   } else {
    return res[columnName]
   }
  }
 }
}
</script>
```

### classの出し分けプロパティを定数管理

```js:HogeTableColumnList.js
import HogeTableColumnName from 'HogeTableColumnName'

export default [
 { property: 'HogeTableColumnName.ID', label: 'ID', isRight: true },
 { property: 'HogeTableColumnName.NAME', label: '名前', isRight: false },
 { property: 'HogeTableColumnName.STATUS', label: 'ステータス', isRight: false },
]
```

```vue
<!-- columnの数だけカラム生成 -->
<template>
 <td
  v-for="column in HogeTableColumnList"
  :class="{ 'is-right': column.isRight }"><!-- idは数字なので右寄せに -->
  <template v-if="column.propery === HogeTableColumnName.STATUS">
  {{ res[column.property].label }}
  </template>
  <template v-else>
  {{ res[column.property] }}
  </template>
 </td>
</template>

<style scoped>
.is-right {
 text-align: right;
 padding-right: 2px;
}
</style>
```

随時更新予定

## 感想
enum管理をしてあげるついでに、ViewModelにあたる情報も定数として管理しておいても良さそうだなという話です。
他にも良さそうな方法あればコメントお願い致します。