2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vuexで複雑にネストしたデータを管理する

Last updated at Posted at 2020-05-02

はじめに

お仕事で複雑にネストしたデータを、複数ページに渡って管理するアプリケーションを作成する必要がありました。
はじめはこちらの記事を参考に、Vuexなしで実装していたのですが、どうやらネストしたデータはバインドできないみたい(?)なので、今更ながらVuexに入門しました。ほとんど調べて出てきた内容を参考にすんなりできたのですが、少し詰まったところがあったのでそこらへんを中心にまとめようと思います。
ソースコードは以下のGitHubリポジトリにおいてあります。(Laravelはまったく使ってません。)
https://github.com/shimech/laravel-vue-demo

環境

  • macOS Catalina 10.15.4
  • PHP 7.4.5
  • Laravel 7.9.2
  • Vue 2.6.11
  • Vuex 3.3.0

ディレクトリ構成

resources
└── js
    ├── bootstrap.js
    ├── components
    │   └── vuex
    │       ├── Check.vue
    │       └── Input.vue
    └── vuex
        ├── app.js
        ├── router.js
        └── store.js

Vuexの仕組み

1. Vuex.Store のインスタンスに、管理したいデータや、そのデータを編集する関数などを定義する。

store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);

const stateTemplate = {
    name: "",
    emailList: [""]
};

const deepCopyObj = obj => JSON.parse(JSON.stringify(obj));

const store = new Vuex.Store({
    state: [deepCopyObj(stateTemplate)],
    mutations: {
        setName(state, { index, name }) {
            state[index].name = name;
        },

        (省略)

    }
});

export default store;

※オブジェクトをディープコピーしないと本体を編集してしまうので注意

Vuex.Store API Reference

2. 1で作成したインスタンスを Vue のインスタンスのプロパティに定義する。

app.js
require("../bootstrap");

import Vue from "vue";

import store from "./store";
import router from "./router";

window.Vue = Vue;

const app = new Vue({
    el: "#app",
    store: store,
    router: router
});

3. 2のVueインスタンスに定義されたVue Componentから、

this.$store.state

store にアクセスできる。
今回は、 vue-router を経由してComponentを定義しています。

router.js
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);

import Input from "../components/vuex/Input.vue";
import Check from "../components/vuex/Check.vue";

const routes = [
    {
        path: "/vuex",
        component: Input
    },
    {
        path: "/vuex/check",
        component: Check
    }
];

const router = new VueRouter({
    mode: "history",
    routes: routes,
    scrollBehavior() {
        return { x: 0, y: 0 };
    }
});

export default router;

詰まったところ

Vuex.Storemutations の関数に複数の引数を渡したい!

A. 第二引数をオブジェクトにするだけ

定義側

store.js
setEmail(state, { indexState, indexEmail, email }) {
    state[indexState].emailList[indexEmail] = email;
}

呼び出し側

Input.vue
updateEmail(indexState, indexEmail, email) {
    this.$store.commit("setEmail", { indexState, indexEmail, email });
}

v-for の中でうまくその要素だけ操作するには?

A. v-for="(item, index) in list"index を渡す

もっといいやり方があれば教えてください。

参考記事

2
1
0

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
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?