有時候可能打到一半不小心關掉,文章就這樣啪..沒了,所以今天想嘗試看看加入自動保存功能來解決這個問題
會使用到 watch 深度監聽和 localstorage 儲存
| 功能 | 工具 | 用處 | 
|---|---|---|
| 偵測表單變化 | watch() | 可監聽 reactive 資料改變 | 
| 保存資料 | localStorage.setItem() | 將資料以字串形式存到瀏覽器 | 
| 載入資料 | localStorage.getItem() | 重新開啟時讀回資料 | 
| 清除草稿 | localStorage.removeItem() | 提交或手動清除草稿時使用 | 
<script setup>
import { reactive, watch, onMounted } from 'vue'
const formData = reactive({
  pSchool: '',
  pDep: '',
  pYear: '',
  pExp: '',
  pResult1: ''
})
const DRAFT_KEY = 'shareFormDraft'
// 讀取草稿
onMounted(() => {
  const saved = localStorage.getItem(DRAFT_KEY)
  if (saved) Object.assign(formData, JSON.parse(saved))
})
// 自動儲存
watch(
  formData,
  (newVal) => {
    localStorage.setItem(DRAFT_KEY, JSON.stringify(newVal))
  },
  { deep: true }
)
// 清除草稿
function clearDraft() {
  localStorage.removeItem(DRAFT_KEY)
}
</script>
前面用 watch 監聽表單變化,但會出現一個問題,如果我每打一個字,就會視為表單內容更新,因此會有大量的寫入,為了避免這狀況發生,可以加入延遲寫入的機制。
主要概念為每次事件觸發後,不立即執行,而是等一小段時間再執行,如果在這段時間內又觸發,就重新計時。在這邊可以設定一個計時器,等使用者停止輸入 0.5 秒後再儲存 。
let timer
watch(
  formData,
  (newVal) => {
    // 每次輸入時清除上一個計時器
    clearTimeout(timer)
    // 重新設定新的計時器
    timer = setTimeout(() => {
      localStorage.setItem('shareFormDraft', JSON.stringify(newVal))
      console.log('草稿已自動儲存')
    }, 500) // 延遲 0.5 秒
  },
  { deep: true }
)
小結
- 讓表單自動儲存
- 加入延遲寫入機制