search
LoginSignup
0

More than 1 year has passed since last update.

posted at

updated at

Organization

Vuexを使用する際にvuex-module-decoratorsを用いて補完を効かせる

はじめに

エンジニアとして働き始めて4ヶ月経ち5ヶ月目に突入したのですが、自分の技術力のなさに絶望しながら日々奮闘しています!

そんな僕が以前から気になっていたVuex+Typescript環境下でインテリセンスが効きにくいと感じていた問題を
解決してくれるvuex-module-decoratorsというものを使用したのでメモとして残しておきます。

install

yarn add -D vuex-module-decorators

npm install -D vuex-module-decorators 

Setup

~/utils/store-accessors.tsではinstallしたモジュールをインポートし、storeに登録します。
また、新しいstoreが出来次第このファイルに追加していきます。

// ~/utils/store-accessors.ts
import { Store } from "vuex";
import { getModule } from "vuex-module-decorators";
import User from "~/store/users";

// 新しいstoreが出来次第以下に追加していく
let usersStore: User;
// let exampleStore: Example

function initialiseStores(store: Store<any>): void {
  usersStore = getModule(User, store);
}

export {
  initialiseStores,
  usersStore,
};

~/store/index.tsではコンポーネントからインポートできるようにstore-accessor.tsのstoreをexportしています。
またstoreを初期化しています。

// ~/store/index.ts
import { Store } from 'vuex'
import { initialiseStores } from '~/utils/store-accessor'
const initializer = (store: Store<any>) => initialiseStores(store) //storeの初期化
export const plugins = [initializer]
export * from '~/utils/store-accessor' //storeをexportする

Storeの作成

こちらはstoreの全体イメージです。
MutationやActionなどは基本的にデコレーターを使用し作成します。
getterとstateはデコレーターを使用しないのは謎ですが、
そんなことはさておき、以下で順を追って解説をしていきます。

// ~/store/users.ts
import { Module, VuexModule, Mutation, Action } from "vuex-module-decorators";
import { $axios } from "~/plugins/api";

export type UserType = {
  name: string;
  age: number;
};

@Module({
  name: "users",
  stateFactory: true,
  namespaced: true,
})
export default class User extends VuexModule {
  private users: UserType[] = [];

  public get getUsers() {
    return this.users;
  }

  @Mutation
  public addUsers(user: UserType) {
    return this.users.push(user);
  }

  @Mutation 
  public setUsers(users: UserType[]) {
    return this.users = users;
  }

  @Action
  public async fetchUsersData() {
    const { data } = await $axios.get<UserType[]>("/api/users/");
    this.setUsers(data);
  }
}

解説

必要なmoduleをインポートする

$axiosActionでapiを叩く際に使用するのでインポートしています。

import { Module, VuexModule, Mutation, Action } from "vuex-module-decorators";
import { $axios } from "~/plugins/api";

型定義

ここでは直接storeファイルに記述していますが、typesフォルダに切り分けて記述した方が綺麗かも。

export type UserType = {
  name: string;
  age: number;
};

Moduleを定義する

  • nameにパスを指定。
  • stateFactory: true とすることで、NuxtがモジュールモードでStoreを作ってくれます。
  • namespced: trueとすることで、名前空間が適用されます
@Module({
  name: "users",
  stateFactory: true,
  namespaced: true,
})

state作成

stateは基本的にクラス内からしかアクセスしないため、privateで定義します。

private users: UserType[] = [];

getter

usersの値を返すgetterです。
stateへはクラス内であればthisでアクセスできます。


  public get getUsers() {
    return this.users;
  }

Mutation

usersのデータをセットするMutationです。
ここでprivateで定義しているのは、ActionからのみMutationを実行するためです。
基本的にMutationはprivateで定義するのがベターかもしれません。

 @Mutation 
  private setUsers(users: UserType[]) {
    return this.users = users;
  }

Action

以下のような非同期処理を実行する際にはAcitonを使用します。
取得したuserのdataを先ほどMutationで定義したsetUsers関数の引数に渡しています。

 @Action
  public async fetchUsersData() {
    const { data } = await $axios.get<UserType[]>("/api/users/");
    this.setUsers(data);
  }

コンポーネント内でActionを実行する

import { usersStore } from "@/store";

const store = usersStore;
store.fetchUsersData(); //Actionを実行。

これでコンポーネント内でActionを実行することができました。
補完も効いてて最高です。
スクリーンショット 2021-12-13 1.36.09.png

おわりに

以前からvuexを使用する際に補完が効かなかったりしてめんどくさいなと思っていたので
今後もVuexを使用する際はこちらを採用しようと思います。
もうcommitやdispatchとはおさらばなのかもしれませんね。

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
What you can do with signing up
0