VueのSPA開発をしていると、定数で管理しておきたいもの(描画する初期値や、何かの一覧など)が多々出てくると思います。
mixinは問題を抱えている、ViewModelにあたるのでできればVuexにも格納したくないと思い、別の方法で考えてみました。
別jsファイルで管理し、require/import(モジュールシステム)で活用
前提
例えば、APIからの返却が下記として、
[
{ id: 1, name: 'Qiita', status: { value: 'active' : label: 'アクティブ' } },
{ id: 2, name: 'Qiitb', status: { value: 'active' : label: 'アクティブ' } },
{ id: 3, name: 'Qiitc', status: { value: 'active' : label: 'アクティブ' } },
]
定数を別jsファイルで管理
まずは、テーブルカラムを定義
consts/hoge/table配下
export default {
ID: 'id',
NAME: 'name',
STATUS: 'status'
}
次に、描画用の情報を定義
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の出し分けプロパティを定数管理
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にあたる情報も定数として管理しておいても良さそうだなという話です。
他にも良さそうな方法あればコメントお願い致します。