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

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

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

mixinは問題を抱えている、ViewModelにあたるのでできればVuexにも格納したくないと思い、別の方法で考えてみました。

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

前提

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

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
image.png

定数を別jsファイルで管理

まずは、テーブルカラムを定義
consts/hoge/table配下

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

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

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(モジュールシステム)で活用

<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でグローバルな定数をコンポーネントで使いまわせるようにしたい
Vue.js公式: インスタンスプロパティの追加 / モジュールシステムを使用する場合

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

応用

templateの例外処理をmethodsに移行

<!-- 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>
<!-- 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の出し分けプロパティを定数管理

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 },
]
<!-- 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にあたる情報も定数として管理しておいても良さそうだなという話です。
他にも良さそうな方法あればコメントお願い致します。

kudo_kk
フロントエンドエンジニア
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