# 24. TodoList 資料模組
可以試著先在 Vuex 處理資料的部分、思考資料怎麼處理,包含路由篩選資料的功能,之後再去建立畫面。
# 開啟嚴格模式
開發的時候,建議先加上 strict: true
,以免不小心改到 state
而不知。
# 初始化,讀取 localStorage
- 先進行資料的初始化,取得 localStorage (以下簡稱 LS) 原有的內容:
- 透過
actions
,取得 LS 的資料。 - 將讀取到的資料,
commit
到mutations
的SET_TODOS
。 - 在
SET_TODOS
將資料更新到state
裡面的todos
。
- 透過
- LS 的處理,建議另外拆分出來管理:
- 取 (load) :將指定的 LS 資料取出,並用
JSON.parse
轉成物件。若 LS 無資料,則預設為空陣列。 - 存 (save) :將資料更新到 LS,並先用
JSON.stringify
轉成字串。
- 取 (load) :將指定的 LS 資料取出,並用
import { createStore } from "vuex";
// 將 LS 的存取拆出來管理
const LS = {
load() { // 取得放在 LS 裡的資料
return JSON.parse(localStorage.getItem("vue-todo") || [])
},
save(data) { // 將資料儲存到 LS
localStorage.setItem("vue-todo", JSON.stringify(data))
}
}
export default createStore ({
strict: true, // 開啟嚴格模式
state: {
todos: [
{ content: "vue-content", complete: false },
{ content: "vue-content", complete: true },
{ content: "vue-content", complete: false },
]
},
mutations: {
SET_TODOS(state, data){ // 將 LS 回傳結果更新到 todos
state.todos = data
LS.save(state.todos)
}
},
actions: {
INIT_TODOS(commit) {
commit("SET_TODOS", LS.load()) // 讀取 LS 以初始化
}
}
})
# 資料的 CRUD
待辦清單有以下基本功能,這些功能都能在 mutations
處理資料,並在更新 state
後將資料存到 LS 裡面:
- 新增事項:將新增的事項推到
todos
陣列。 - 修改事項:將陣列中索引值為
index
的內容更新為傳入的data
。 - 刪除事項:將陣列中索引值為
index
的資料移除。
mutations: {
SET_TODOS(state, data){
state.todos = data
LS.save(state.todos)
},
// 新增事項
ADD_TODO(state, data) {
state.todos.push(data)
LS.save()
},
// 修改事項
UPDATE_TODO(state, {index, data}) {
state.todos[index] = data
LS.save()
},
// 刪除事項
REMOVE_TODO(state, index) {
state.todos.splice(index, 1)
LS.save()
}
},
但上面修改事項的寫法會有問題,之後會說明並進行修改。
# 資料的篩選
我們會透過切換路由去呈現不同狀態的資料。我們可以像 LS 那樣,在 export default
之外 ,將資料的篩選功能額外管理。
const LS = {
// 略 ...
}
// 將篩選功能獨立出來管理
const filter = {
all(todos) {
return todos
},
active(todos) {
return todos.filter(todo => !todo.complete)
},
complete(todos) {
return todos.filter(todo => todo.complete)
}
}
export default createStore ({
// 略 ...
})
# getters 抓出索引值
事項的更新和刪除都需要知道其索引值,才能準確對指定事項進行操作。
- 使用
getters
取得state
中todos
的索引值。 - 根據所在的路由 (
state.route.name
),從state.todos
篩選出符合條件的事項。 - 將篩選後的符合事項,用
indexOf
查找其索引值,透過map
使查找結果成為一個新的陣列。
getters: {
todoIndex(state) {
return filter[state.route.name](state.todos).map(todo => state.todos.indexOf(todo))
}
},