Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?
@ysKuga

JavaScript での Vuex にて getters や actions などの定義で state を推論して中身を確認しながら実装する

JavaScript でも Vuex 定義時に推論をしたい

TypeScript の場合は Vuex and Typescript - codeburst などをさんこうにしましょう
JavaScript で TypeScript のような推論を行う事例として

モジュールモードですぐに Vuex の store が使用できる Nuxt.js にてやります

state の定義

Vuex and Typescript では ProfileState, RootState をそれぞれ定義しています。
Vuex の Getter や Action が <S, R> などとしてもとめているからです

RootState にあたるもの

「中身」の Stateexport 対象にしているところがポイントです
Vuex and Typescript にて定義されている interface RootState の代わりとかんがえてください
Statestate でわかりずらいかもしれないのでこの変数定義はあんまりよくないかもしれません

store/index.js
export const State = {
  'ba-john': 'ichi'
}

export const state = () => Object.assign({}, State)

ProfileState と同じ位置づけのもの

モジュールモードなので export default で定義したら勝手にモジュールになります
こっちも State を定義して export 対象としています

store/profile/state.js
/**
 * @typedef {Object} State
 * @property {string} namae なまえ
 */

/** @type {State} */
export const State = {
  namae: 'ichi'
}

export default () => Object.assign({}, State)

getters 定義

getters の定義の際には Vuex より Getterimport しましょう
さらに state で定義しておいたそれぞれの State をそれぞれ import して
getter として定義する変数に JSDoc にて @type を指定します。

下記の例は State をそれぞれ RootLocal として別名にしています

store/profile/getters.js
/**
 * @typedef {import('@/store').State} RootState
 * @typedef {import('./state').State} State
 */
/** @type {import('vuex').GetterTree<State, RootState>} */
const getters = {
  getNamae: (state) => state.namae,
}
export default getters 

にょきにょき生えてくる state の中身

このようにして actions や mutations にも Vuex の Action<S,R> Mutation<S>
適切な state のオブジェクトを指定することで推論がきくようになります

mutations 定義

つごうにより actions の前に mutations を定義します

store/profile/mutations.js
/**
 * @typedef {import('./state').State} State
 */

// Mutation は state, payload が明示されればよく、
// また、 MutationTree を指定してしまうと mutations のプロパティが推論できなくなるようなので
// MutationTree を指定するメリットが現状少なそう
///** @type {import('vuex').MutationTree<State>} */
const mutations = {
  /**
   * @param {State} state
   * @param {{ namae: string }} payload
   */
  setNamae: (state, payload) => {
    state.namae = payload.namae
  },
}

export default mutations

actions 定義

他と同様 Vuex の Action の定義の仕方に従って actions.js を定義していますが・・・
同僚の mutations もインポートしています
これは mutations の定義を流用してその推論により commit をする際の参考にしております
(これは是非があるでしょうが・・・)

store/profile/actions.js
/**
 * @typedef {import('@/store').State} RootState
 * @typedef {import('./state').State} State
 */
/** @type {import('vuex').ActionTree<State, RootState>} */
const actions = {
  /**
   * @param {{ namae: string }} payload
   */
  setNamae: (context, payload) => {
    // 定義名を利用して commit を実施
    context.commit(mutations.setNamae.name, payload)
  },
}
export default actions

Action での context にはいろいろと格納されているので
推論で中身がみれたほうが便利と思われます

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?