0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Vue.js】トーストで表示するエラーの状態をPiniaで管理

Posted at

はじめに

REST APIのエラー時、ステータスコード及びエラーメッセージをユーザーにトーストで通知したい。

上記の記事でコンポーザブルによる実装を検討したが、2階層のデータの受け渡しをPropsで行っていることやページを遷移した際もデータを保持したいことなどを考慮し、ストアライブラリであるPiniaを用いた実装を行う。

Pinia

  • Vue3のストア(Store)ライブラリでコンポーネントをまたいで状態を共有、管理できる
  • データへの変更、加工処理もまとめて管理できる
  • Propsでは親子関係のコンポーネント間のデータを受け渡ししかできなかったが、全てのコンポーネントでデータを共有できる
  • キャラクターがかわいいね

image.png

  • 以前はVuexが使われたいたが、現在はメンテナンスモードで新規機能は追加されない

前提条件

  • 既にPiniaをインストール済みのプロジェクト
  • main.tsapp.use(createPinia())を呼んでいる

Storeの作成

  • 一意のid 'error' を指定
  • state
    • データ本体
      • status: HTTPレスポンスのステータス
      • message: HTTPレスポンスのエラーメッセージ
    • 初期値を設定しておく
  • actions
    • データの変更処理
      • set: 引数としてstatusmessageを受け取り更新
      • clear: 状態を初期化
  • getters
    • データの状態を基に計算された値を取得
      • isSet: 現在エラーが設定されているかを判定
      • statusが0以上またはmessageが空でない場合true
stores/error.ts
import { defineStore } from 'pinia'

export const useError = defineStore('error', {
  state: () => ({
    status: -1,
    message: '',
  }),
  actions: {
    set(status: number, message: string) {
      this.status = status
      this.message = message
    },
  },
  getters: {
    isSet: (state) => state.status >= 0 && state.message !== '',
  },
})

コンポーネントからのStoreの利用

App.vue
<templete>
// isSetがtrueの場合トーストを表示
<div v-if="error.isSet" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
  <div class="toast-header">
    <img src="..." class="rounded me-2" alt="...">
    <strong class="me-auto">Bootstrap</strong>
    <small>11 mins ago</small>
    <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
  </div>
  <div class="toast-body">
    Hello, world! This is a toast message.
  </div>
</div>
</templete>

<script setup lang="ts">
// defineStore()の結果をインポート
import { useError } from '@/stores/error.ts'

// インポートしたuseErrorを関数として実行し、その結果を変数として格納
// 変数がStoreのオブジェクトととなる
const error = useError()

.
.
.
// REST API呼び出し部分でエラーが発生した場合ステータスとエラーメッセージをStoreにセット
error.set(res.status, res.error.message)
</script>

stateのリセット

  • stateの状態を初期値に戻す場合は以下を利用できる
error.$reset()

Vue.js Devtools

  • ブラウザの拡張機能でVue.js Devtoolsがインストールされていれば、開発者ツールのVueタブの中にPiniaタブがある
  • ストア内の状態を確認できる

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?