Created
January 18, 2018 06:11
-
-
Save duncan60/f38e83eb14fe4b3a2f369048fc625012 to your computer and use it in GitHub Desktop.
Vue Todo with Vuex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
<script src="//cdn.jsdelivr.net/npm/vue"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script> | |
</head> | |
<body> | |
<h1>Vue Todo with Vuex</h1> | |
<div id="app" > | |
<div> | |
<p>Need Todo</p> | |
<ul> | |
<todo-item | |
v-for="(item, key) in unCompleteTodos" | |
:todo="item" | |
:key="key" | |
:edit="onEdit" | |
:save="onSave" | |
:complete="onComplete"> | |
</todo-item> | |
<li> | |
<input | |
placeholder="Enter text" | |
v-model="newTodo" | |
v-on:keyup.stop="updateField('newTodo', $event.target.value)" | |
> | |
<button @click="onAddTodo" :disabled="isDisabled"> | |
add new todo | |
</button> | |
</li> | |
</ul> | |
</div> | |
<div> | |
<p>Complete Todo</> | |
<ul> | |
<todo-item | |
v-for="(item, index) in completeTodos" | |
:todo="item" | |
:key="item.id" | |
:restore="onRestore"> | |
</todo-item> | |
</ul> | |
</div> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// vuex store | |
const ADD_NEW_TODO = 'ADD_NEW_TODO'; | |
const UPDATE_TODO = 'UPDATE_TODO'; | |
const UPDATE_FIELD = 'UPDATE_FIELD'; | |
const store = new Vuex.Store({ | |
state: { | |
newTodo: '', | |
todos: { | |
1:{ id:1, text: '學習 JavaScript', isEdit: false, isComplete: false }, | |
2:{ id:2, text: '學習 Vue', isEdit: false, isComplete: false }, | |
3:{ id:3, text: '學習 React', isEdit: false, isComplete: true } | |
} | |
}, | |
getters: { | |
getTodos: state => isComplete => { | |
list = {} | |
for (let [k, v] of Object.entries(state.todos)) { | |
if(v.isComplete === isComplete) { | |
list[k] = v; | |
} | |
} | |
return list; | |
} | |
}, | |
mutations: { | |
[ADD_NEW_TODO]: (state, payload) => { | |
newId = parseInt(1000*Math.random()); | |
new_todo = { | |
id: newId, | |
text: state.newTodo, | |
isEdit: false, | |
isComplete: false | |
} | |
state.todos = { | |
...state.todos, | |
[newId]: new_todo, | |
}; | |
state.newTodo = ''; | |
}, | |
[UPDATE_TODO]: (state, payload) => { | |
state.todos[payload.id] = { | |
...payload, | |
}; | |
}, | |
[UPDATE_FIELD]: (state, payload) => { | |
state[payload.field] = payload.value; | |
} | |
}, | |
actions: { | |
addNewTodo: ({ commit }) => { | |
commit(ADD_NEW_TODO); | |
}, | |
updateTodo: ({ commit }, todo) => { | |
commit(UPDATE_TODO, todo); | |
}, | |
updateField: ({ commit }, fieldObj) => { | |
commit(UPDATE_FIELD, fieldObj); | |
} | |
} | |
}) | |
// vue component | |
Vue.component('todo-item', { | |
props:['todo', 'edit', 'save', 'complete', 'restore'], | |
data() { | |
return { | |
text: this.todo.text, | |
} | |
}, | |
methods: { | |
onHandler(type) { | |
this[type](this.todo, this.text); | |
} | |
}, | |
template: ` | |
<li v-if="!todo.isEdit && !todo.isComplete"> | |
<span> | |
{{ text }} | |
</span> | |
<button @click="onHandler('complete')"> | |
complete | |
</button> | |
<button @click="onHandler('edit')"> | |
edit | |
</button> | |
</li> | |
<li v-else-if="todo.isComplete"> | |
<span> | |
{{ todo.text }} | |
</span> | |
<button @click="onHandler('restore')"> | |
restore | |
</button> | |
</li> | |
<li v-else> | |
<input type="text" v-model="text"> | |
<button @click="onHandler('save')"> | |
save | |
</button> | |
</li> | |
` | |
}) | |
const app = new Vue({ | |
el: '#app', | |
store, | |
computed: { | |
unCompleteTodos() { | |
return this.$store.getters.getTodos(false); | |
}, | |
completeTodos() { | |
return this.$store.getters.getTodos(true); | |
}, | |
newTodo() { | |
return this.$store.state.newTodo; | |
}, | |
isDisabled() { | |
return this.$store.state.newTodo !== '' ? false : true; | |
} | |
}, | |
methods: { | |
updateTodos(todo) { | |
this.$store.dispatch('updateTodo', todo); | |
}, | |
updateField(field, value) { | |
this.$store.dispatch('updateField', {field, value}); | |
}, | |
onAddTodo() { | |
this.$store.dispatch('addNewTodo'); | |
}, | |
onEdit(todo) { | |
this.updateTodos({ | |
...todo, | |
isEdit: true, | |
}); | |
}, | |
onSave(todo, newText) { | |
this.updateTodos({ | |
...todo, | |
text: newText, | |
isEdit: false, | |
}); | |
}, | |
onComplete(todo) { | |
this.updateTodos({ | |
...todo, | |
isComplete: true | |
}); | |
}, | |
onRestore(todo) { | |
this.updateTodos({ | |
...todo, | |
isComplete: false | |
}); | |
} | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
url: https://jsbin.com/wayuda/edit?html,js,output