Nuxt.jsでブログのような比較的シンプルなアプリケーションを構築するような場合でも、”独自の関数を1度だけ定義し、都度importすること無く使いたい” といったケースがあります。
たとえば、「pagesディレクトリの各pageコンポーネントで必ず使う関数がある」などです。
Nuxt.jsではpluginsを使うことで独自関数を外部化でき、関数の呼び出しもスムーズになり、別々のコンポーネントで同じ記述をするといった冗長なコードを避けられます。
私はmicroCMSを用いたブログの構築の際に、日付の処理に関して上記のケースに当たりましたので実装方法を紹介します。
実行環境:
Node 14.19.0
Nuxt.js 2.15.8
dayjs 1.9.8
yarn 1.21.1
pluginsを使った外部関数化の例(サンプルコード)
microCMSを例にとると、microCMSのAPIはcreatedAtやpublishedAtなどの日付データを世界時間で返します。
この場合、日本時間と9時間ずれるようですので、APIを叩いただけだと想定した時刻を取得できません。
上記ヘルプセンターでも「dayjsライブラリ」を用いた解決方法が示されていますが、ブログの更新日・公開日(createdAtやpublishedAt)等を複数のページで使用している場合、各ページでimportをするのは手間です。
そこでNuxt.jsに実装されているplugins機能を用いてdayjsのimportを1度きりにし、必要なときにサクッと呼び出せる形で定義します。
以下が実際のコードになります。
ライブラリのインストールとサンプルコード
dayjsをプロジェクトにインストールします
npm i -S dayjs
もしくは
yarn add dayjs
/pluginsフォルダ内に外部関数となるjsファイルを作成します
世界時間→日本時間への変換コードはmicroCMSヘルプセンター の記述を参考にしています。
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
dayjs.extend(utc)
dayjs.extend(timezone)
export default ({ app }, inject) => {
inject('tokyoTime', (data) =>
dayjs.utc(data).tz('Asia/Tokyo').format('YYYY-MM-DD')
)
}
pluginsの使用例はNuxt.jsのドキュメントで詳しく解説されています。
このコードは、各pageコンポーネント内でtokyoTime関数(好きな名前でOK)に引数(data)で世界時間を渡して呼び出し、日本時間で返ってくるものになります。
injectはNuxt.jsに実装されたメソッドで、外部で使用する関数を定義するときに使われます。
nuxt.config.jsに作成した外部関数ファイルを記載
export default {
plugins: ['~/plugins/change-day.js']
}
pluginsに記載することで、pageコンポーネント等で簡単に呼び出せるようになります。
pageコンポーネントで独自関数を呼び出す
asyncData内で呼び出す例
export default {
async asyncData({ params, $microcms, app }) {
const data = await $microcms.get({
endpoint: `blog/${params.id}`,
})
return {
publishedAt: app.$tokyoTime(data.publishedAt),
createdAt: app.$tokyoTime(data.createdAt),
}
},
ブログの記事ページの例です。
microCMSのAPIから返ってきたデータ(data.publishedAtやdata.createdAt)を
※今回はplugins/change-day.jsで「app」を指定しているので、tokyoTime関数前の app.$ は必須です。
plugins内に書いた関数の呼び出し方法は、Nuxt.jsのバージョンによって違いがあります。詳しくはドキュメントを参照してください。
Nuxt.jsドキュメント〜plugins〜
Vueファイルのtemplate内で呼び出す例
<div v-for="item in contents" :key="item.id">
{{ $tokyoTime(item.publishedAt) }}
</div>
日付を10桁でsliceするならこんな感じでしょうか。
<div v-for="item in contents" :key="item.id">
{{ `${$tokyoTime(item.publishedAt).slice(0, 10)}` }}
</div>
Nuxt.jsのpluginsの仕様がわかっていないと「いきなり出てくる$tokyoTime関数って何?!」となりますが、頻度の高い同様の処理をこのような簡単な記述で書けるのはメリットが大きいですね。
- メンテナンス性
- コードの可読性
という面で、非常によく考えられた仕様かと思います。
おわりに
Nuxt.jsのバージョンが低かった頃は、pluginsに/components配下のファイルをimportするjsファイルを作成し、よく呼び出すコンポーネントは都度importしなくても使えるように効率化を図りました。
しかし最近のバージョンでは、nuxt.config.jsファイルに
export default {
components: true,
}
と書くだけで、/components配下のvueファイルは呼び出し先でimportしなくとも自動で読み込まれるようになりました。便利ですね。
Nuxt.jsのバージョンアップが進めば、独自関数の設定方法も更に便利になるのかも知れませんね^^
コメント