こんにちは!
最近は Typescript を使用したフロントエンド開発がデファクトスタンダードとなってきました。NuxtJS は VueJS をより開発しやすく、便利に扱える仕組みをいくつも搭載しています。NuxtJS は Typescript とも非常に相性が良いので、保守性高く開発を行うことが可能ですね。
本記事では、私たちが普段利用するテクニック「Vue.filter
で State のフォーマット化共通実装」をご紹介します!
NuxtJS は、Vue3のComposition API をアドオンで提供していますが、2021年7月現在、NuxtJS は Vue3 自体にはまだ非対応の様子です。しかし、それを差し引いても NuxtJS の数多くの VueJS 開発便利機能の提供と、SSR の実装しやすさは魅力的です。プロジェクトで SSR 要件がある場合はぜひ NuxtJS の導入を検討してみてください。対して、必ず Vue3 を利用したいといったプロジェクトの場合は、NuxtJS 導入は要検討です。
私たちの経験上、前述の通り NuxtJS は Vue3 の Composition API について はアドオンで利用できるので、SSR 要件があるのであれば開発効率の観点で NuxtJS を推奨します。
Vue.filter
を NuxtJS の Vue インスタンスにバインドさせるために、NuxtJS のプラグイン機能を活用します。
export default {
...
plugins: [
{ src: '@/plugins/index.ts', mode: 'client' },
],
...
}
Vue.filter
を用途によって定義します。全ての Vue ファイルで共通利用するために、再利用可能な汎用的な名称・機能で作成することを推奨します。以下は実装例です。
import Vue from 'vue'
import moment from 'moment'
import {
ProductCategory,
} from '~/graphql/API'
Vue.filter('displayDateTime', function (dateString?: string): string {
if (!dateString) return ' - '
return moment(dateString).format('YYYY年MM月DD日 HH:mm')
})
Vue.filter(
'displayProductCategory',
function (category?: ProductCategory): string {
if (!category) return ' - '
return {
[ProductCategory.ConsumerElectronics]: '家電',
[ProductCategory.HealthyFood]: '健康食品',
[ProductCategory.Clothes]: '洋服',
[ProductCategory.OfficeSupplies]: '事務用品',
}[category]
}
)
API の型情報(enum
, type
等)を定義します。Amplify が導入されているプロジェクトの場合、amplify codegen
で作成するファイルとなります。
export enum ProductCategory {
ConsumerElectronics = 'ConsumerElectronics',
HealthyFood = 'HealthyFood',
Clothes = 'Clothes',
OfficeSupplies = 'OfficeSupplies',
}
では、プラグインに定義したVue.filter
を Vue ファイルで利用します。以下は簡易な商品詳細ページの例です。
<template>
<div>
<p>商品名:{{ product.name }}</p>
<p>発売日:{{ product.publishedAt| displayDateTime }}</p>
<p>カテゴリー:{{ product.category| displayProductCategory }}</p>
</div>
</template>
上記の例のように、Vue.filter
はパイプで値を渡すだけで簡単に利用することができます。
// JS部分
import { Vue, Component } from 'nuxt-property-decorator'
import { Context } from '@nuxt/types'
import { productStore } from '~/store'
@Component({
async asyncData(context: Context) {
const { store, route } = context
await Promise.all([
store.dispatch('productStore/getProductById', {
Id: route.params.id
}),
])
},
})
export default class Index extends Vue {
get product(){
return productStore.getProduct
}
}
実践では Vue.filter
の定義が /plugins/index.ts
に増えてきたら、Vue.filter
を定義するファイルを分割することも検討してみてください。
私たちは、特に State の物理名を論理名に変換したい場合に積極的に利用しているテクニックとなります。
各 Vue ファイルに State のフォーマット用の関数定義を行うのは、保守性・開発効率が悪化するので、ぜひ Vue.filter でフォーマット用の関数の共通実装を検討してみてください。
NuxtJS & VueJS、Typescript の開発は、お気軽にお問い合わせください。
スモールスタート開発支援、サーバーレス・NoSQLのことなら
ラーゲイトまでご相談ください
低コスト、サーバーレスの
モダナイズ開発をご検討なら
下請け対応可能
Sler企業様からの依頼も歓迎