PR

Pinia × Vue Router:アクションからrouter.push()を使うとエラーが出た場合の対処

pinia Javascript
記事内に広告が含まれています。
スポンサーリンク

Piniaを使った状態管理で、アクションからVue Routerのrouter.push()を呼び出そうとしてエラーに悩まされることはありませんか?この記事では、「PiniaのアクションでVue Routerを正しく使う方法」をテーマに、TypeScriptの型拡張や設定の具体例を交えて解説します。

スポンサーリンク

前提

本記事は、下記を利用したプロジェクトであることを前提とします。

  • vue
  • pinia
  • vue-router
  • typescript

目次

  1. PiniaとVue Routerの連携における課題
  2. 実装の基本構成と解決策の概要
  3. 解決案
  4. エラー対策とトラブルシューティング

1. PiniaとVue Routerの連携における課題

PiniaはVue.js公式の状態管理ライブラリで、Vue Routerはルーティングの標準ライブラリです。これらを組み合わせることで、洗練されたWebアプリケーションが構築可能ですが、Piniaのストア内のアクションからVue Routerを使おうとすると型エラーが発生するという課題に直面することがあります。

よくあるエラーの例

Property 'router' does not exist on type '{ actions... }'.ts(2339)

これはPiniaにVue Routerの型が登録されていないためです。

2. 実装の基本構成と解決策の概要

この問題を解決するためには、以下の3ステップを実施します。

  1. TypeScriptの型定義を拡張する
    Piniaの型にrouterを追加します。
  2. Vue Routerインスタンスをリアクティブ性から除外する
    markRaw()を使い、PiniaのプラグインでVue Routerインスタンスを設定します。
  3. アクション内でrouter.push()を活用する
    型安全にナビゲーションを実行可能になります。

3. 解決案

1. TypeScriptの型定義を拡張する

型定義ファイルの作成

プロジェクトのsrc/types/pinia.d.tsに以下のコードを記述します。

src/types/pinia.d.ts

import 'pinia';
import { Router } from 'vue-router';

declare module 'pinia' {
  export interface PiniaCustomProperties {
    router: Router;
  }
}

これにより、Piniaのカスタムプロパティにrouterが追加されます。

tsconfig.jsonの確認

TypeScriptに型定義を認識させるため、tsconfig.jsonに以下を追加してください:

tsconfig.json

{
  "compilerOptions": {
    "typeRoots": ["./node_modules/@types", "./src/types"]
  }
}

2. Vue Routerインスタンスをリアクティブ性から除外する

以下は実際のコード例です。
main.ts

import { createPinia } from 'pinia';
import { createApp, markRaw } from 'vue';
import { router } from './router';

const pinia = createPinia();

pinia.use(({ store }) => {
  store.router = markRaw(router); // routerをstoreに追加
});

const app = createApp(App);
app.use(pinia);
app.use(router);
app.mount('#app');

ストアのアクションでの利用

import { defineStore } from 'pinia';

export const useAppStore = defineStore('app', {
  actions: {
    navigateToPage(path: string) {
      this.router.push(path);
    },
  },
});

4. エラー対策とトラブルシューティング

発生する可能性のあるエラーと対策

  • エラー: Property 'router' does not exist on type
    • 対策: pinia.d.tsの内容とファイル配置を再確認。
  • エラー: Router.push is not a function
    • 対策: markRaw(router)が正しく設定されているかチェック。

まとめ

PiniaとVue Routerを連携させ、アクションでrouter.push()を型安全に利用する方法について解説しました。この手法を取り入れることで、開発効率が向上し、エラーのリスクを最小化できます。

Webアプリケーション開発をスムーズに進めるための一助になれば幸いです!

参考情報

Vue.js公式ドキュメント

Pinia公式ガイド

Vue Router公式ドキュメント

コメント

タイトルとURLをコピーしました