# 26. TodoList 頁面模組 2 - 列表
這個小節主要說明「列表顯示」模組。
# 新增「列表顯示」模組
在 "components" 資料夾建立 "TodoListItem" 資料夾,並在裡面新增以下檔案:
- index.vue
- template.html
# template.html
這個模組內有這些組成:
<input type="checkbox">
勾選是否完成。<label>
呈現待辦事項的內容。<button>
用來刪除事項。
//- components/TodoListItem/template.html
<div class="todoListItem">
<input type="checkbox" class="toggle" v-model="complete"/>
<label>{{ todo.content }}</label>
<button class="destroy" @click="destroyHandler"></button>
</div>
# index.vue
- 接收索引值
- 使用
props
接收外部傳入的索引值index
- 這個模組會呈現所有待辦事項中的其中一筆,因此需要知道索引值,才能知道要呈現的是哪一筆資料。
- 使用
- 抓取該索引值內容
- 拿到索引值後,使用
computed
抓該筆索引值的內容。
- 拿到索引值後,使用
- 刪除事項
- 點擊
<button>
觸發destroyHandler
- 先確認是否要刪除,以免誤刪。
- 如果確定,就
commit("REMOVE_TODO", this.index)
,刪除傳入的索引值項目。
- 點擊
- 修改事項狀態 (是否完成)
- 由於 Vuex 不能直接改
state
的資料,因次不能在input
使用v-model="todo.complete"
綁定並修改todo
。 - 取而代之,我們可以在
computed
建立一個變數complete
,綁定到input
上。也就是v-model="complete"
,這樣就不會直接改到 store 的內容。 complete
裡面會有get
和set
兩個功能:get
取得此索引值資料的完成狀態。set
透過commit
去更新此 store 中此筆資料的完成狀態。
- 如果要進行修改,依據先前在 mutation 裡面寫的
UPDATE_TODO
,參數需要同時傳入索引值index
以及整包資料data
。
- 由於 Vuex 不能直接改
//- components/TodoListItem/index.vue
<script>
export default {
props: {
index: {
type: Number,
required: true
}
},
computed: {
todo(){
return this.$store.state.todos[this.index]
},
complete: {
get(){
return this.todo.complete
},
set(val){
this.$store.commit("UPDATE_TODO", {
index: this.index,
data: {
content: this.todo.content,
complete: val
}
})
}
}
},
methods: {
destroyHandler(){
if(confirm(`是否確認刪除 ${this.todo.content} ?`))
this.$store.commit("REMOVE_TODO", this.index)
}
}
}
</script>
<template src="./template.html"></template>
# 使用「列表顯示」模組
同樣地,我們要在 "App.vue" 引入以使用模組。
//- App.vue
<template>
<div id="nav">
<router-link :to="{name: 'all'}">全部</router-link> |
<router-link :to="{name: 'active'}">未完成</router-link> |
<router-link :to="{name: 'complete'}">已完成</router-link>
</div>
<TodoInput/>
// 在輸入框底下用 v-for 陳列 TodoListItem
// 記得要綁定 key,並傳入參數 index 到模組以顯示該筆資料
<div id="list">
<TodoListItem v-for="index in todoIndex" :key="index" :index="index"/>
</div>
</template>
<script>
import TodoInput from "./components/TodoInput/index.vue"
import TodoListItem from "./components/TodoListItem/index.vue"
export default {
components: {
TodoInput,
TodoListItem
},
// 略 ...
}
</script>