前回のカウンターアプリに引き続き、今回はTODOアプリを作ってみようと思います。
基本は、前回お話ししたので、今回は、前回説明してこなかった部分に注力を置いて説明します。
まだVue.jsの初心者をちょっと超えたぐらいですが・・・
まずVue.jsとVuexでアプリを組むには、アプリの全体像をイメージし、
どんな画面で、どんなイベントがあって、どんな値を保持しなければならないかをしっかりと把握する。
画面の絵なんか描くといいかもですね。
で、今回の出来上がりイメージはこんな感じ。

ページ上部に、新しいTODOを入力する場所があって、追加すると、下に新たなTODOとして表示される。
表示されたTODOの文字をクリックすると、処理済みになり、削除をクリックすると、リストから削除される。
これだけです。
では、Vuexのstore作成いってみましょう!!
値を保持しなければならないものは以下の2つ
・TODOのアイテム全て
・新しいTODOの入力途中の文字
ユーザーの操作でアクションが起こる場所
・追加ボタンで新しいTODOが追加
・TODOの文字列クリックで、処理済み
・削除ボタンで、リストから削除
storeから取得したいもの
・TODOのアイテム全て
・新しいTODOの入力途中の文字
ではまず、mutation-type.jsに定義すべき変数です。
src/store/mutation-type.js
[bash]
export const ADD_TODO = ‘ADD_TODO’
export const DONE_TODO = ‘DONE_TODO’
export const REMOVE_TODO = ‘REMOVE_TODO’
export const GET_TODOS = ‘GET_TODOS’
export const CHANGE_MYSTRING = ‘CHANGE_MYSTRING’
[/bash]
次、storeを定義しましょう。
src/store/todo.js
[bash]
import { ADD_TODO, DONE_TODO, REMOVE_TODO, CHANGE_MYSTRING, GET_TODOS } from ‘./mutation-type’
const todo = {
namespaced: true,
state: {
items: [],
mystring: ”
},
actions: {
[ADD_TODO] ({commit, state, rootState}, newValue) {
let newItem = {
todo: newValue,
is_done: false
}
commit(ADD_TODO, {data: newItem})
commit(CHANGE_MYSTRING, {data: ”})
},
[DONE_TODO] ({commit, state, rootState}, selItem) {
commit(DONE_TODO, {data: selItem})
},
[REMOVE_TODO] ({commit, state, rootState}, selItem) {
commit(REMOVE_TODO, {data: selItem})
}
},
mutations: {
[ADD_TODO] (state, payload) {
state.items.push(payload.data)
},
[DONE_TODO] (state, payload) {
state.items.map(it => {
if (it.todo == payload.data.todo){
it.is_done = !it.is_done
}
})
},
[REMOVE_TODO] (state, payload) {
for (let i = 0; i < state.items.length; i++){
if (state.items[i].todo == payload.data.todo){
state.items.splice(i, 1)
break
}
}
},
[CHANGE_MYSTRING] (state, payload) {
state.mystring = payload.data
}
},
getters: {
[GET_TODOS] (state, getters, rootState) {
return state.items
}
}
}
export default todo
[/bash]
storeのルートファイル、 modulesに todo も追加しましょう。
[bash]
import Vue from 'vue'
import Vuex from 'vuex'
import counter from './counter'
import todo from './todo'
Vue.use(Vuex)
const store = new Vuex.Store({
modules :{
'counter': counter,
'todo': todo,
}
})
export default store
[/bash]
次にフロントエンドです。
ちょっとここは説明を加えておきます。
Todoの1つを表すのは Leafコンポーネントです。
mapGettersで取得した todos を v-forでループさせます。
LeafコンポーネントのプロパティにTotoアイテムの1つのデータを引き渡します。
新しいTodoの文字は入力途中のものも全て管理します。
つまり IN/OUT双方向管理です(v-model)。
その場合は computedに xxxx を用意して、そこに
get/set を作ります。
ネストしたストアですが、取得は素直に
this.$store.state.todo.mystring
コミットの方はちょっと工夫します。
this.$store.commit('todo/' + CHANGE_MYSTRING, {data: value})
1つ1つのTODOを表す Leafコンポーネントは componentsで定義しておきます。
src/components/Todo.vue
[bash]
[/bash]
Leafコンポーネントについて
親から引き渡された プロパティを propsで受けます。
あとは特殊なところといえば、v-bind:class で クラスのオンオフを制御しているところでしょうか。
[bash]
[/bash]
最後にルートファイルの編集です。
[bash]
import Vue from ‘vue’
import Router from ‘vue-router’
import HelloWorld from ‘@/components/HelloWorld’
import Counter from ‘@/components/Counter’
import Todo from ‘@/components/Todo’
Vue.use(Router)
export default new Router({
routes: [
{
path: ‘/’,
name: ‘HelloWorld’,
component: HelloWorld
},
{
path: ‘/counter’,
name: ‘Counter’,
component: Counter
},
{
path: ‘/todo’,
name: ‘Todo’,
component: Todo
}
]
})
[/bash]
npm run dev して
http://localhost:8080/#/todo
で表示されます。
すごく説明をすっ飛ばしましたが、カウンターアプリのソースの説明を合わせて読むと
理解いただけると思います。
前回のカウンターと今回のTODOアプリのソースを添付します。(vue4th.zip)
ダウンロードして、そのフォルダ内で、npm install すれば使えると思います。
Leave a comment