mountedをvuex化したい。
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 481
環境
windows10(64)
"vue": "^2.6.10",
"vuetify": "^2.1.0",
"vue-cli":"3.11.0",
"node":"v11.13.0"
プログラミング歴 5か月ほど
やりたいこと
vuetify+vue-cliでtodoアプリ(講義さぼり回数カウントアプリ)を作っています。
授業名を入力してEnterを押すことで、欠席回数をカウントできるリストが出力されます。
下記URLです↓
https://vuejs-http-e3587.firebaseapp.com/
もちろんjsのlocalStorageという機能を使ってカウントもメモも永続化しています。
今まで、vuexを使っていなかったのでこれらをvuexに書き変えようとしました。
vuexに書き変えていない正常に動くブランチのソースコード
Count.vue
<template>
<v-app>
<v-content>
<v-container>
<v-row>
<v-col cols="6">
<v-text-field v-model="name" label="授業名" @keyup.enter="addTodo" required></v-text-field>
</v-col>
</v-row>
<div v-for="(todo,index) in todos" :key="todo.name">
<v-card card_id max-width="344" class="mx-auto">
<v-card-title>{{todo.name}}</v-card-title>
<v-card-text>
<v-text-field label="メモ" v-model="todo.memo" @input="addMemo"></v-text-field>
</v-card-text>
<v-card-actions>
<v-btn @click="increment(todo)" color="primary">さぼり回数</v-btn>
<span>{{ todo.count }}</span>
<v-btn @click="decrement(todo)" color="error">間違い(-)</v-btn>
<v-btn @click="deleteItem(index)">削除</v-btn>
</v-card-actions>
</v-card>
</div>
</v-container>
</v-content>
</v-app>
</template>
<script>
export default {
data() {
return {
count: 0,
name: "",
todos: [],
memo: []
};
},
mounted() {
this.todos = JSON.parse(localStorage.getItem("todos")) || [];
},
methods: {
templateJson() {
let setJson = JSON.stringify(this.todos);
localStorage.setItem("todos", setJson);
},
addMemo() {
this.templateJson();
this.isActive = false;
},
addTodo() {
if (this.name != "") {
this.todos.push({
name: this.name,
count: 0
});
}
this.templateJson();
this.name = "";
},
increment(todo) {
todo.count++;
this.templateJson();
},
decrement(todo) {
if (todo.count > 0) {
todo.count--;
}
this.templateJson();
},
deleteItem(index) {
this.todos.splice(index, 1);
let setJson = JSON.stringify(this.todos);
localStorage.removeItem("todos");
localStorage.setItem("todos", setJson);
}
}
};
</script>
vuexに書き変えた際の問題点
悩んだ点として、mountedのthis.$store.state.todos =
JSON.parse(localStorage.getItem("this.$store.state.todos")) ||
の部分をvuexに書き変える部分が分かりませんでした。
一応、データを扱っていたので、gettersで書き変えを試みましたが、授業名を入力すると次のようなエラーを吐きました。
下記ソースコードです。↓
Count.vue
<template>
<v-app>
<v-content>
<v-container>
<v-row>
<v-col cols="6">
<v-text-field v-model="$store.state.name" label="授業名" @keyup.enter="addTodo" required></v-text-field>
</v-col>
</v-row>
<div v-for="(todo,index) in ($store.state.todos)" :key="todo.name">
<v-card card_id max-width="344" class="mx-auto">
<v-card-title>{{todo.name}}</v-card-title>
<v-card-text>
<v-text-field label="メモ" v-model="todo.memo" @input="addMemo"></v-text-field>
</v-card-text>
<v-card-actions>
<v-btn @click="increment(todo)" color="primary">さぼり回数</v-btn>
<span>{{ todo.count }}</span>
<v-btn @click="decrement(todo)" color="error">間違い(-)</v-btn>
<v-btn @click="deleteItem(index)">削除</v-btn>
</v-card-actions>
</v-card>
</div>
</v-container>
</v-content>
</v-app>
</template>
<script>
import { mapActions } from "vuex";
export default {
data() {
return {};
},
mounted() {
this.$store.state.todos = this.$store.getters.getItemJson;
},
methods: {
...mapActions([
"templateJson",
"increment",
"decrement",
"addMemo",
"addTodo",
"deleteItem"
])
}
};
</script>
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0,
name: "",
todos: [],
memo: []
},
getters: {
getItemJson(state) {
state.todo = JSON.parse(localStorage.getItem("state.todos")) || [];
}
},
mutations: {
templateJson(state) {
state.todos = JSON.parse(localStorage.getItem("state.todos")) || [];
let setJson = JSON.stringify(state.todos);
localStorage.setItem("state.todos", setJson);
},
addMemo() {
this.templateJson();
this.isActive = false;
},
addTodo(state) {
if (state.name != "") {
state.todos.push({
name: state.name,
count: state.count
});
}
state.name = "";
this.templateJson();
},
increment(state) {
state.count++;
this.templateJson();
},
decrement(state) {
if (state.count > 0) {
state.count--;
}
this.templateJson();
},
deleteItem(state, index) {
state.todos.splice(index, 1);
let setJson = JSON.stringify(state.todos);
localStorage.removeItem("state.todos");
localStorage.setItem("state.todos", setJson);
}
},
actions: {
toggleSideMenu({ commit }) {
commit("toggleSideMenu")
},
templateJson({ commit }) {
commit("templateJson")
},
addMemo({ commit }) {
commit("addMemo")
},
addTodo({ commit }) {
commit("addTodo")
},
deleteItem({ commit }, index) {
commit("deleteItem", index)
},
increment({ commit }, state) {
commit("increment", state)
},
decrement({ commit }, state) {
commit("decrement", state)
},
}
})
自分のエラーの原因の考察
templateJsonメソッドで、データを保存しているのですがmounted(gettersの getItemJsonメソッド)でデータを取得した実装がうまくいってないので結果的にデータ保存ができていない。自分の見解はこんな感じです。
mountedの部分をvuexでどのように書き変えればvuex書き変え前と変わらない挙動ができますか?
アドバイスあればお願いします。
全コード
➀ vuex書き変え前の上手く挙動する方のブランチのソースコード↓
https://github.com/masal9pse/courageTodo/tree/develop
➁ vuex書き変え後の動かないブランチのソースコード
https://github.com/masal9pse/courageTodo/tree/vuex
参考にしたサイト
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
ストアの値はミューテーションからのみ変更することができます。また、ゲッターはストアのデータを抽出するための機能ですのでゲッターからストアへ値をセットする方法は誤りとなります。
mountedの処理は以下のようにすれば注入可能だと思います。
mutations: {
setTodos(state) {
state.todo = JSON.parse(localStorage.getItem("state.todos")) || [];
}
}
mounted() {
this.$store.commit('setTodos')
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.19%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる