はじめに
お仕事で複雑にネストしたデータを、複数ページに渡って管理するアプリケーションを作成する必要がありました。
はじめはこちらの記事を参考に、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;
※オブジェクトをディープコピーしないと本体を編集してしまうので注意
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.Store
の mutations
の関数に複数の引数を渡したい!
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
を渡す
もっといいやり方があれば教えてください。