nuxt.js の From の state 管理を考える

2021/09/25

nuxt.js

vue.js

はじめに

nuxt.js での Form の処理を考える。
nuxt-typed-vuexcomption-api は導入済み。

Form の状態を管理する state の定義

form に入力された情報を commit したときに保持する state を定義する。

import { getterTree, mutationTree, actionTree } from "typed-vuex";
import { Form } from "@/types/form";

export const state = (): Form => ({
  text1: "",
  text2: "",
});

export type RootState = ReturnType<typeof state>;

export const getters = getterTree(state, {
  get(state) {
    return state;
  },
});

export const mutations = mutationTree(state, {
  init(state) {
    state.text1 = "";
    state.text2 = "";
  },
  set(state, payload: Form) {
    Object.assign(state, payload);
  },
});

export const actions = actionTree({ state, getters, mutations }, {});

Form の状態を使った Api リクエストを保持する state の定義

Form の状態とパラメータとして Api リクエストの状態管理する state を定義する。
ただ今回は実際にリクエストをしていないのでそこは状況に合わせて変更する。
またアクション(dispatch)の引数として使うパターンと state の状態を使うパターン 2 種類定義し、場合に合わせて使い分けする。(基本的は state の方を使う)

import { getterTree, mutationTree, actionTree } from "typed-vuex";
import { Form } from "@/types/form";

export interface ApiResponse {
  res: any;
}

export const state = (): ApiResponse => ({
  res: {},
});

export type RootState = ReturnType<typeof state>;

export const getters = getterTree(state, {
  get(state) {
    return state;
  },
});

export const mutations = mutationTree(state, {
  setResponse(state, payload) {
    Object.assign(state, payload);
  },
});

export const actions = actionTree(
  { state, getters, mutations },
  {
    // paramからリクエスト
    async getResponseWithParams({ commit }, { param }: { param: Form }) {
      const res = {}; // 何かしらの処理
      commit("setResponse", res);
    },
    // stateにある状態からリクエスト
    async getResponseWithState({ commit }) {
      const param = this.app.$accessor.formState.get;
      const res = {}; // 何かしらの処理
      commit("setResponse", res);
    },
  }
);

From のコンポーネント

今回はテスト的にやるので HTML 側は適当。

<template>
  <form @submit="submit">
    <div>
      <label for="text1">text1</label>
      <input id="text1" name="text1" type="text" v-model="text1" />
    </div>
    <div>
      <label for="text2">text2</label>
      <input id="text2" name="text2" type="text" v-model="text2" />
    </div>
    <button>submit</button>
  </form>
</template>

<script>
  import { defineComponent, ref } from "@vue/composition-api";
  import { useContext } from "@nuxtjs/composition-api";

  export default defineComponent({
    setup() {
      const { app } = useContext();
      const text1 = ref("");
      const text2 = ref("");
      const submit = (e) => {
        e.preventDefault();
        app.$accessor.formState.init();
        app.$accessor.formState.set({
          text1: text1,
          text2: text2,
        });
        app.$accessor.apiSend.getResponseWithParams({
          param: app.$accessor.formState.get,
        });
        app.$accessor.apiSend.getResponseWithState();
      };
      return {
        submit,
        text1,
        text2,
      };
    },
  });
</script>

終わりに

今回はとりあえず form の状態を管理するだけ、バリデーション等は考慮していない。
state 側に色々処理を追加することもできると思うけど肥大すると思うので他ライブラリ等で解決するのもいいかなと。
また今回のソースコードは こちら にある。