--- title: '2019/10/21 VueJS 教學筆記: 緩存機制' disqus: hackmd --- 10/21 VueJS 教學筆記: 緩存機制 === 綱要 [TOC] 學習如何使用暫存,並比較三種方式之間的不同 --- ==**Cookies**== 可設置失效時間,未指定時間則是關閉瀏覽器就失效,儲存容量約 4 KB。 與其他兩種方式不同,缺點是會夾帶在HTTP中,當保存了過多的資料時會影響效能。 ==**Local Storange**== 永久保存,除非進行清除,有 5 MB 左右的儲存容量。 不參與 Server 溝通,僅保存在瀏覽器中。 ==**Session Storange**== 關閉頁面或瀏覽器後會自動進行清除,同樣有 5 MB 左右的儲存容量、其它特性與 Local Storange 相同。 練習:LocalStorange 的例子 --- [Codepen範例](https://codepen.io/fortes-huang/pen/MWWbdxz) **Context:** 1. 避免填寫到一半的表單因為斷線、重新整理、或誤關閉網頁造成必須從頭開始填寫狀況 2. 為了方便再次進入填寫步驟時可以自動帶入User上一次的填寫內容,需要載入已儲存的欄位內容 **Force:** 1. 使用Local Storange將輸入一半的表單內容保留,重新整理時務必顯示已填寫的部分內容 2. 當按下「載入上一次填寫的內容」時,完整的自動填寫上一次「成功送出」後的所有欄位 題解 --- [Github範例](https://github.com/fortes1219/vue_0803/blob/0803/src/components/home/LocalStorange.vue) `data()`中定義表單綁定的 v-model ```javascript= data() { return { form: { name: '', prefer: '', date: '', time: '', type: [] }, savedForm: {}, preferItems: [ { id: 0, name: 'Ruler' }, { id: 1, name: 'Saber' }, { id: 2, name: 'Archer' }, { id: 3, name: 'Lancer' }, { id: 4, name: 'Rider' }, { id: 5, name: 'Caster' }, { id: 6, name: 'Assassin' }, { id: 6, name: 'Berserker' }, { id: 8, name: 'Avenger' }, { id: 9, name: 'Alterego' }, { id: 10, name: 'Foreigner' } ] } } ``` 在`methods`中增加重置表單的方法: ```javascript= methods: { // 建議把這個resetForm()另外編入utils做export const共用方法 resetForm(target) { let reset = (obj) => { Object.keys(obj).map(key => { if (obj[key] === Object(obj[key])) { reset(obj[key]) if (obj[key] instanceof Array) { obj[key] = [] } return } else { obj[key] = '' } }) } reset(target) } handleReset(obj) { this.resetForm(obj) obj.date = '' obj.time = '' }, } ``` 接著是`template`的部分,因為需求中有「避免填寫到一半的表單因為斷線、重新整理、或誤關閉網頁造成必須從頭開始填寫狀況」,所以透過綁定表單物件`@change` 事件,當內容變更時就寫入暫存。 ```htmlmixed= <el-form ref="form" :model="form" label-width="150px" style="width: 600px"> <el-form-item label="御主姓名"> <el-input v-model="form.name" @change="onChangeItem"></el-input> </el-form-item> <el-form-item label="偏好職階"> <el-select v-model="form.prefer" placeholder="請選擇偏好職階" @change="onChangeItem"> <el-option v-for="(item, index) in preferItems" :key="index" :label="item.name" :value="item.id"></el-option> </el-select> </el-form-item> <el-form-item label="申請時間"> <el-col :span="11"> <el-date-picker type="date" placeholder="選擇日期" v-model="form.date" style="width: 100%;" @change="onChangeItem"></el-date-picker> </el-col> <el-col :span="11"> <el-time-picker placeholder="選擇時間" v-model="form.time" style="width: 100%;" @change="onChangeItem"></el-time-picker> </el-col> </el-form-item> <el-form-item label="想成為御主的理由"> <el-checkbox-group v-model="form.type" @change="onChangeItem"> <el-checkbox label="可以和好多女性從者這個那個" name="type"></el-checkbox> <el-checkbox label="拯救世界" name="type"></el-checkbox> <el-checkbox label="可以拿好多好多的聖晶石" name="type"></el-checkbox> <el-checkbox label="我是興趣使然的御主" name="type"></el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item> <el-button type="primary" @click="loadLastData">載入上一次填寫內容</el-button> <el-button type="primary" @click="onSubmit">送出申請</el-button> <el-button @click="handleReset(form)">重置表單</el-button> </el-form-item> </el-form> ``` 在`methods`增加一個事件處理`onChangeItem()`: ```javascript= methods: { onChangeItem() { // 每次輸入input或者勾選了checkBox、變更select時,兩秒後自動寫入localStorange setTimeout( () => { // 如果不在寫入時先將物件轉JSON字串,則寫入結果只會顯示 [object object] localStorage.setItem('form', JSON.stringify(this.form)) }, 2000) }, } ``` 頁面載入時就撈回剛剛填到一半的進度: ```javascript= methods: { // onChangeItem() //... reloadSavedForm() { // 使用JSON.parse()將LocalStorange中的資料轉回可利用的object const stored = JSON.parse(localStorage.getItem('form')) if (stored !== null) { this.form = stored } } }, created() { // created階段時就進行 this.reloadSavedForm() } ``` 最後是成功送出表單後,需要儲存已送出的內容: ```javascript= methods: { // onChangeItem() // reloadSavedForm() //... // 表單送出 onSubmit() { localStorage.setItem('submitSuccess', JSON.stringify(this.form)) }, // 載入前一次成功送出的內容 loadLastData() { this.savedForm = JSON.parse(localStorage.getItem('submitSuccess')) this.form = this.savedForm } } ``` Cookies 的例子 --- 先安裝 [js-cookie](https://github.com/js-cookie/js-cookie) `npm install js-cookie` 定義 Cookies 設置、取得、移除三個行為: ```javascript= import Cookies from 'js-cookie' // ... methods: { setCookies() { // 這裡的expires設置 1 的時候是指「一天內有效」,根據js-cookie官方文件記載,還支援new Date()的方式設置有效時間 // 寫入時同樣要注意是否轉JSON字串的問題 Cookies.set('cookie', JSON.stringify(this.form), { expires: 1 }) }, removeCookies() { Cookies.remove('cookie') }, getCookies() { this.savedForm = JSON.parse(Cookies.get('cookie')) console.log(this.stored) } } ``` ###### tags: `VueJS` `LocalStorange` `Cookies`