這篇文章主要在記錄如何用 vue + vuex + vue-router
做出一個簡單的 TODO List 專案
DEMO 網站
Source Code
先來訂一個 TODO List 的簡單需求表
- 能夠輸入項目
- 能夠打勾確認完成
- 能夠刪除項目
- 能夠選擇顯示全部, 未完成, 完成的項目
程式部分則會分為一個 vuex store 和三個 components
- 專門控管資料的 store
- 輸入項目 component
- 顯示項目 compoent
- 選擇完成狀態的 component
專門控管資料的 store
store.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex) const store = new Vuex.Store({ state: { lists: [], status: '', counter: 0 }, mutations: { addItem (state, new_item) { state.counter += 1 new_item.id = state.counter state.lists.push(new_item) }, changeStatus(state, id) { state.lists = state.lists.map((list) => { if (list.id === id) list.is_completed = !list.is_completed return list }) }, deleteItem(state, id) { state.lists = state.lists.filter((list) => { if (list.id === id) return false; return true; }) } } }) export default store;
|
輸入項目 component
todo-input.vue
1 2 3 4 5 6 7 8
| <div> <form class="ui form" @submit.prevent="submit"> <div class="field"> <label for="">List</label> <input type="text" v-model="item"> </div> </form> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| export default { data() { return { item: '' } }, methods: { submit() { this.$store.commit('addItem', { name: this.item, is_completed: false }) this.item = '' } } }
|
顯示項目 component
todo-item.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <div> <table class="ui table stackable fixed"> <thead> <tr> <th colspan="3">Item</th> </tr> </thead> <tbody> <tr v-for="(list, index) in lists"> <td :class="{completed: list.is_completed}"> {{list.name}} </td> <td> <button class="ui icon inverted green button" @click="done(list.id)"> <i v-if="list.is_completed === false" class="checkmark icon"></i> <i v-else class="reply icon"></i> </button> </td> <td> <button class="ui icon inverted red button" @click="remove(list.id)"> <i class="trash icon"></i> </button> </td> </tr> </tbody> </table> </div> <style scoped lang="css"> .completed { text-decoration: line-through } </style>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| export default { computed: { status () { return this.$store.state.status }, lists() { return this.$store.getters.filtered_list } }, methods: { remove(id) { this.$store.commit('deleteItem', id) }, done(id) { this.$store.commit('changeStatus', id) } } }
|
選擇完成狀態的 coomponent
todo-display.vue
1 2 3 4 5 6 7
| <div> <select class="ui dropdown" v-model="status"> <option value="">Show All</option> <option value="done" selected>Show Done</option> <option value="nondone">Show None-done</option> </select> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12
| export default { computed: { status: { get () { return this.$store.state.status }, set (value) { this.$store.commit('setFilter', value) } } } }
|