くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

vuex-classを使うとNuxt+TSのModuleなStoreがスッキリかけた

またまた Nuxt公式サンプルから。

vuex-classを使うとStoreのState/Getter/Actionなどを
アノテーションで紐付けれるらしい。。なにこれ、超便利。。

page/componentsの部分

こんな感じでできるよう。。すごい。。

import { Component, Vue } from 'vue-property-decorator'
import { namespace } from 'vuex-class'

import * as people from '~/store/modules/people'

const People = namespace(people.name)

@Component
export default class IndexPage extends Vue {
  @People.State selected
  @People.State people
  @People.Getter selectedPerson
  @People.Action select
}

storeの部分

ディレクトリ構成はこんな感じ。

store/
  - modules/
    - people.ts  ... モジュールのstore
  - root.ts      ... rootのstore
  - index.ts     ... index。各ストアをVuex.Storeにまとめてる

store/index.ts

import Vuex from 'vuex'
import * as root from './root'
import * as people from './modules/people'

export type RootState = root.State

const createStore = () => {
  return new Vuex.Store({
    state: root.state(),
    getters: root.getters,
    mutations: root.mutations,
    actions: root.actions,
    modules: {
      [people.name]: people
    }
  })
}

export default createStore

store/root.ts

import { GetterTree, ActionContext, ActionTree, MutationTree } from 'vuex'
import axios from 'axios'
import { RootState } from 'store'

export const types = {}

export interface State {}

export const state = (): State => ({})

export const getters: GetterTree<State, RootState> = {}

export interface Actions<S, R> extends ActionTree<S, R> {
  nuxtServerInit (context: ActionContext<S, R>): void
}

export const actions: Actions<State, RootState> = {
  async nuxtServerInit ({ commit }) {
    // ...
  }
}

export const mutations: MutationTree<State> = {}

store/modules/people.ts

import { ActionTree, MutationTree, GetterTree, ActionContext } from 'vuex'
import { RootState } from 'store'

export const name = 'people'

export const types = {
  SELECT: 'SELECT',
  SET: 'SET'
}

export interface Person {
  id: number
  name: string
}

export interface State {
  selected: number
}

export const namespaced = true

export const state = (): State => ({
  selected: 1,
  people: []
})

export const getters: GetterTree<State, RootState> = {
  selectedPerson: state => {
    const p = state.people.find(person => person.id === state.selected)
    return p ? p : { first_name: 'Please,', last_name: 'select someone' }
  }
}

export interface Actions<S, R> extends ActionTree<S, R> {
  select (context: ActionContext<S, R>, id: number): void
}

export const actions: Actions<State, RootState> = {
  select ({ commit }, id: number) {
    commit(types.SELECT, id)
  }
}

export const mutations: MutationTree<State> = {
  [types.SELECT] (state, id: number) {
    state.selected = id
  },
  [types.SET] (state, people: Person[]) {
    state.people = people
  }
}

かなりスッキリに。。すごい。

以上!!

参考にしたサイト様