はじめに
REST APIのエラー時、ステータスコード及びエラーメッセージをユーザーにトーストで通知したい。
トーストをコンポーネント化し、呼び出し処理を各ページに実装していたが、冗長であることに気づいた。
▼トーストの親コンポーネント(変更前)
<template>
// propsでステータスコード、エラーメッセージをトーストに渡す
<Toast v-if="isToastVisible" :message="errorMessage" :status="errorStatus"></SpToast>
</template>
<script setup lang="ts">
import Toast from '@/components/Toast.vue'
// ステータスコード
const errorStatus = ref<number>(0)
// エラーメッセージ
const errorMessage = ref<string | null>(null)
// トースト表示/非表示のフラグ
const isToastVisible = ref<boolean>(false)
.
.
.
// トースト表示処理
errorStatus.value = res.status
errorMessage.value = res.error.message
isToastVisible.value = true
トーストの呼び出し処理をコンポーザブル(Composable)で再利用可能にする。
コンポーザブル(Composable)とは?
Vue3のComposition APIにおいて状態を持つロジックをカプセル化してまとめた関数。コンポーネント間で共通するロジックを使いまわすことができる。
Reactでは似た機能をカスタムフックと呼ぶらしい。
トーストの呼び出し処理のコンポーザブル化
上記に書いたコードをコンポーザブルとして外部に切り出してみる。
▼コンポーザブル
import { ref } from 'vue'
// 慣習としてコンポーザブル関数の名前は"use"で始める
export function useToast() {
// コンポーザブルによってカプセル化および管理される状態
const errorStatus = ref<number>(0)
const errorMessage = ref<string | null>(null)
const isToastVisible = ref<boolean>(false)
// トースト表示処理
const showToast = (status: number, message: string) => {
errorStatus.value = status
errorMessage.value = message
isToastVisible.value = true
}
// 提供する値と関数を返す
return {
errorStatus,
errorMessage,
isToastVisible,
showToast,
}
}
コンポーザブルを呼び出し元のページから呼び出す
▼トーストの親コンポーネント(変更後)
<template>
// propsでステータスコード、エラーメッセージをトーストに渡す
<Toast v-if="isToastVisible" :message="errorMessage" :status="errorStatus"></SpToast>
</template>
<script setup lang="ts">
import useToast from './useToast.ts'
const { errorStatus, errorMessage, isToastVisible, showToast } = useToast()
showToast(res.status, res.error.message)
元のコードよりだいぶスッキリして再利用性・可読性・保守性が向上したと考えられる。