🙄

Vue 3 + Typescript + Piniaで状態管理

2022/12/15に公開

前書き

Vue3をインストールしたときにPiniaのサンプルとして入っているcounter.tsが、関数を使ったコードに変わっていた為、記事にまとめようと思いました。

nodeのバージョンは v16.17.0 で行っております

本題

インストール

今回の開発は以下の方法でインストールしています。

npm init vue@latest
✔ Project name: … vue-pinia
✔ Add TypeScript? … Yes
✔ Add JSX Support? … No
✔ Add Vue Router for Single Page Application development? … Yes
✔ Add Pinia for state management? … Yes
✔ Add Vitest for Unit Testing? … No
✔ Add an End-to-End Testing Solution? › No
✔ Add ESLint for code quality? … No

counter.tsについて

今回の前書きにある、counter.tsについて確認します。
/src/stores/counter.tsを開いてみましょう。

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})

2022/12現在では上記になっており、以前までは下記のコードとなっていました。
調べても下記のコードの記事が多いかと思います。

import { defineStore } from 'pinia'

interface State {
  count: number
}

export const useCounterStore = defineStore("counter", {
  state: (): State => ({ count: 0 }),
  getters: {
    doubleCount: (state) => {
      return state.count * 2
    }
  },
  actions: {
    increment() {
      this.count++
    }
  }
})

見比べてみる

基本的な(id: ストア名, state: データ本体定義,getters: データ加工処理定義,actions: データ変更処理定義)の考え方は変わっていません。
それでは見比べていきましょう。

state

以前のコード
state: (): State => ({ count: 0 })
関数でのコード
const count = ref(0)

refを使ったコードに変わっています。ちなみに、refを使って型指定を行う場合は、ジェネリクス引数を与えてあげることで指定できます。

現在のコードで型指定
const count = ref<number>(0)

getters

以前のコード
  getters: {
    doubleCount: (state) => {
      return state.count * 2
    }
  }
関数でのコード
  const doubleCount = computed(() => count.value * 2)

stateをrefで管理することで、stateへのアクセスが変わりました。
またgettersは、stateの値をもとに算出した結果を取得するので、同じ動きをするcomputedを使っています。

actions

以前のコード
  actions: {
    increment() {
      this.count++
    }
  }
関数でのコード
  function increment() {
    count.value++
  }

actionsもgettersと同じでrefを使ったstateへのアクセスになっています。

その他

idのコードは変わっていませんので、第一引数に書いていただければ大丈夫です。
他に変わったところといえば、最後のreturnでしょうか。
defineStoreをexportしていればそのまま使えていましたが、関数での書き方ではstate, getters, actions全てをreturnをしなければなりません。

後書き

見てくださった方はどちらのコードの方がよかったでしょうか。
個人的には関数でのコードの方が感覚的に書けて、書きやすいと感じました。
また、OpenWeatherMapを使って、今回の本題の書き方でGitHubに上げていますので、宜しければ参考にして下さい。

Discussion