未完成
事項與完成
的事項分開存放首先我會從 getter 下手,分開撈取: 未完成
/ 完成
export const getDone = state => {
return state.todos.filter((item) => {
return item.done;
});
}
export const getTodo = state => {
return state.todos.filter((item)=>{
return !item.done;
});
}
修改為兩隻 getter 因 getter 不能傳值 (可以傳請告訴我..)
使用 filter 過濾 item.done
分開撈取: 未完成 / 完成
<template>
<div class="container">
<h1>vue & vuex Todo List example</h1>
<hr>
<div class="row">
<div class="input-group col-md-4">
<input
type="text"
class="form-control"
placeholder="add Todo.."
v-model="newTodo"
@keyup.enter="actionAddTodo" />
<span class="input-group-btn">
<button class="btn btn-success" type="button" @click="actionAddTodo">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
</span>
</div>
</div>
<!-- 左右兩個欄位分別存放 todo / done -->
<div class="row">
<div class="col-md-6">
<h2>Todo List:</h2>
<li v-for="(item, index) in todoList">
<label>
<!--
改變狀態
套用 vuex 因此不能使用 v-model 做雙向綁定,會報錯誤
1. 將 list 的 value bind 到 input checked 屬性上,改變樣式。
2. onchange 事件發出 action 帶入 key
-->
<input
type="checkbox"
:checked="item.done"
@change="toggleTodo( item.key )">
{{ item.content }}
</label>
<!--
刪除按鈕
onclick 事件發出 action 帶入 key
-->
<button class="btn btn-xs btn-danger" @click="deleteTodo( item.key )">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
</li>
</div>
<div class="col-md-6">
<h2>Done List:</h2>
<ul >
<li v-for="(item, index) in doneList">
<label>
<input
type="checkbox"
:checked="item.done"
@change="toggleTodo( item.key )">
{{ item.content }}
</label>
</li>
</ul>
</div>
</div><!-- end row -->
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
data () {
return {
newTodo: ''
}
},
computed: mapGetters({
todoList: 'getTodo',
doneList: 'getDone',
}),
methods: {
...mapActions([
'toggleTodo',
'deleteTodo',
]),
actionAddTodo () {
this.$store.dispatch('addTodo', this.newTodo);
this.newTodo = '';
}
}
}
</script>
到這便順利完成,分開兩張表顯示。
export const toggleTodo = ({ commit }, key) => {
commit(types.TOGGLE_TODO, key);
}
export const deleteTodo = ({ commit }, key) => {
commit(types.DELETE_TODO, key);
}
action 目前都還很單純只把 key 帶給 metution
// 改變狀態
[types.TOGGLE_TODO] (state, key) {
for(var i in state.todos){
var item = state.todos[i];
if ( item.key === key){
item.done = !item.done;
console.log('TOGGLE_TODO:', item.content, 'done?', item.done);
break;
}
}
},
// 刪除
[types.DELETE_TODO] (state, key) {
for(var i in state.todos){
var item = state.todos[i];
if ( item.key === key){
console.log('DELETE_TODO:', item.content, ', index?', i);
state.todos.splice(i, 1);
break
}
}
},
這邊用比較簡單的 for 迴圈,將傳進來的 key 找到 todo, 把狀態反向,更新 state。
一樣是找到 todo 後單純將 todo Array 從 splice 出去。
state 更新的時候 gatter 就會撈取新的狀態,反映到 Vue 上面。
掌握 vuex 了嗎? 邏輯寫在
metution
因為只有它可以改變state
state 改變gatter
會更新Vue
完成數據驅動
你只需要操縱 JSON !
實作小範例入門 Vue & Vuex 2.0 - github 完整範例
使用 git checkout 切換每天範例。
我的Delete 和 Toggle 是這樣, 進行了簡化
[types.DELELTE_TODO] (state, key) {
var index = state.todos.findIndex(item => item.key === key)
state.todos.splice(index, 1)
console.log(`TODOS DELETED. key: ${key}, index: ${index}`)
},
[types.TOGGLE_TODO] (state, key) {
var item = state.todos.find(item => item.key === key)
item.done = !item.done
console.log('TOGGLE_TODO: ', item.content, 'done?', item.done)
}
getter 也做了些簡化:
export const getTodos = state => state.todos.filter(item => !item.done)
export const getDoneTodos = state => state.todos.filter(item => item.done)
hi garrodran99,
當初在寫這篇的時候,想法是直觀的表現 function 在做什麼,所以故意用最簡單的寫法很醜很蠢那種,目的就是不要讓大家一眼看不出來在做什麼,或者要在去看 ES6 語法或者 array 操作語法這樣。
我覺得這樣的學習是很跳躍的,主要是當初在公司內部介紹的時候發現這樣的情況,如果我寫這些語法讓程式變美變簡潔,反而讓第一次看的人跳脫了 vuex 的流程
介紹這個主軸,跑去注意 ES6
語法,或者有種學 vuex 就要學 ES6 的感覺(當然一定要)但是我要先讓他們先喜歡、暸解、覺得 vuex 流程可以解決目前開發上遇到的困難這樣(然後再推坑 ES6 這樣)。
非常感謝你在留言中,正確的示範套用 ES6 語法可以多麽的省略,簡潔,直觀的開發。
還有想問下, this.newTodo = ''; 這個放在組件裡面直接修改, 是不是不太好?
newTodo 我覺得也要放進去 mutation 裡面修改, 因為 addTodo 不保證一定成功, 應該等成功後才清空的.
改變狀態
套用 vuex 因此不能使用 v-model 做雙向綁定,會報錯誤
1. 將 list 的 value bind 到 input checked 屬性上,改變樣式。
2. onchange 事件發出 action 帶入 key
我把:checked="item.done"
@change="toggleTodo( item.key )">
刪掉, 直接改成 v-model="item.done"
, 完全沒有任何問題啊. toggle 那個 method 也沒有用了.
但想了想, 應該不容許這種直接修改, 我再研究一下