2025-02-04- JavaScript 系列八:第5課 ── 體重追蹤應用程式-程式結構

2025-02-04- JavaScript 系列八:第5課 ── 體重追蹤應用程式-程式結構


🔧 程式結構總覽

這個 weightTrackerApp.vue 是一個 Vue 3 組件,使用了:

功能 技術 說明
UI 設計 Tailwind CSS 控制版面與排版(像是 flex、w-1/4、rounded 等)
狀態管理 refcomputed 用來追蹤使用者輸入與記錄資料
資料儲存 localStorage 存入瀏覽器本地,資料不會消失
圖表 Chart.js 繪製體重變化折線圖(透過 CDN 引入)
DOM 操作 refnextTick 操作 canvas 畫圖表

🧱 程式邏輯分成幾個區塊

newRecord:使用者的輸入

1
2
3
4
const newRecord = ref({
date: '',
weight: null,
})

這是一個響應式資料,綁定表單的 v-model。使用者每次輸入的日期與體重都暫存在這裡。


records:所有紀錄(會被存到 localStorage)

1
const records = ref([])

這個陣列儲存所有已輸入的紀錄,每一筆格式如下:

1
2
3
4
5
{
id: 1683901019283, // 唯一值(用 Date.now() 產生)
date: '2025-05-07',
weight: 55.2
}

③ 排序後的紀錄:sortedRecords

1
2
3
const sortedRecords = computed(() => {
return [...records.value].sort((a, b) => new Date(a.date) - new Date(b.date))
})

這個 computed 屬性會產生依照日期排序的清單,讓畫面與圖表都按照時間順序顯示。


④ 加入記錄與刪除記錄

1
2
3
4
5
6
7
const addRecord = () => {
// 檢查有填資料才加入
records.value.push({...})
}
const deleteRecord = (id) => {
records.value = records.value.filter(r => r.id !== id)
}

每新增/刪除資料,畫面與 localStorage 都會更新。


⑤ 自動儲存到 localStorage + 重新繪圖

1
2
3
4
watch(records, (newVal) => {
localStorage.setItem('weight-records', JSON.stringify(newVal))
nextTick(() => renderChart())
}, { deep: true })

每當 records 發生變化,就會自動儲存到 localStorage,並重新繪製圖表。


renderChart():用 Chart.js 畫圖

1
2
3
4
const renderChart = () => {
// 銷毀舊圖表
// 根據 sortedRecords 的資料畫新圖
}

這個函數會根據資料畫出折線圖,用來顯示體重變化趨勢。


⑦ 版面配置(使用 Tailwind)

1
2
3
4
<div class="flex flex-col md:flex-row gap-6">
<div class="w-full md:w-1/4">...</div> <!-- 輸入表單 -->
<div class="w-full md:w-3/4">...</div> <!-- 清單+圖表 -->
</div>

這段用 flex 將畫面切成兩欄:

  • 小畫面(手機)是直的:flex-col
  • 大畫面(桌機)是橫的:md:flex-row
  • 左側是 1/4,右側是 3/4