在填寫多步驟式的表單資料時,若需要在回上一步後顯示先前填寫過的資料,可以使用 keep-alive 標籤包裹,讓指定的步驟組件狀態被快取,輕鬆完成這類需求。
前言
故事的開端在於筆者依據需求完成了一個多步驟式的表單填寫功能,而當時需求只有單方向的填寫,並無返回上一步的功能;正當大夥都興高采烈的準備收工時,客戶突然覺得應該要有「上一步」才比較人性化!
這時腦中瞬間浮現了許多實作的思路 (就是資料傳來傳去 or 存放在 Vuex 中來保留狀態),總之就是麻煩事一件。好在下個瞬間我就突然想起之前在爬官方文件有瞄到什麼 keep 啥的東西,似乎就是我需要的東西,因此本文簡單介紹一下 keep-alive 的使用情境囉。
keep-alive 簡介
Vue 本身內建 keep-alive
組件用於快取包在這個組件內的組件資料及狀態,使原本需要被摧毀 (destroy) 的組件,避免被摧毀且保持原有的狀態,因此若需保留組件狀態可以用 keep-alive
標籤包裹起來即可;當然我們也可以指定那些組件才需要被快取,keep-alive
提供了兩個 prop 供開發者使用:
- include: 標記「需要」被快取的組件名稱 (其餘都不快取)
- exclude: 標記「不需」被快取的組件名稱 (其餘全部快取)
以上兩種參數都可以擺放 String, RegExp 或 Array 型態資料
以下範例示範三種傳入 include 屬性的資料格式,皆表示當動態組件 view 名稱為 a 或 b 的時候,該組件會被快取起來(不被摧毀);當 view 改為其他動態組件後再切回 a 或 b 組件時,先前填寫的資料會依舊存在畫面上。
<!-- comma-delimited string -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- regex (use `v-bind`) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- Array (use `v-bind`) -->
<keep-alive :include="['a', 'b']">
<component :is="view"></component>
</keep-alive>
activated
與 deactivated
兩個新事件作為組件顯示及離開的觸發時機。
單向填寫表單 - 無保存資料
在實作這種步驟式表單,筆者習慣會在單個 page 組件中擺放各步驟表單組件,然後透過 step 來切換顯示需呈現的畫面;這樣的好處就是當用戶無論在哪個步驟中,只要按下瀏覽器左上角的上一頁鍵,會回到進入表單的入口頁,不會有機會透過瀏覽器上下頁來「隨意地」在各步驟中遊走,最多僅能依照頁面上提供的功能按鍵來順著規畫邏輯切換填寫步驟。
無提供「上一步」功能的頁面組件代碼約略如下,透過 step 來切換顯示需呈現的表單組件。
<template>
<div>
<!-- 挑選旅遊國家 -->
<step1-tour v-if="step===1" @done="goNext" />
<!-- 填寫遊客資料 -->
<step2-passenger v-if="step===2" @done="goNext"/>
<!-- 確認資料無誤 -->
<step3-confirm v-if="step===3" @done="goNext" />
</div>
</template>
<script>
import step1Tour from './components/step1Tour'
import step2Passenger from './components/step2Passenger'
import step3Confirm from './components/step3Confirm'
export default {
name: 'BookTour',
data () {
return {
step: 1
}
},
methods: {
goNext: function () {
this.step += 1
}
},
components: {
step1Tour,
step2Passenger,
step3Confirm
}
}
</script>
套用 keep-alive 保存資料
一般表單填寫的邏輯通常會保留前步驟填寫過的資料,且在返回後再進入下個步驟時,清空表單並依照前步驟輸入的資料初始新步驟選單資料,所以簡單歸納以下兩個需求。
- 保留當前步驟「前」的所有填寫資料
- 移除當前步驟「後」的所有填寫資料
要如何有效率的控制須保存的步驟資料,最好的方法就是一切都是全自動,可以透過 step 的變化來自動定出須保存的表單組件範圍,因此首先需要先訂出 flowSteps 來決定各步驟所對應的表單組件清單;接著定義 aliveInclude 計算屬性,可隨著 step 變化來動態計算當下需要保留狀態的表單組件清單。最後將這個清單導入 keep-alive 的 include 屬性,告知當前步驟需保存的表單組件範圍,而其他不須保存的資料也會一併清除。
實作的示意步驟如下:
- 加入回上一步的事件 (可切回上個 step 位置 )
- 定義步驟編號及對應的表單組件名稱 (flowSteps)
- 依據當前步驟 step 篩選出需保存表單組件清單 (aliveInclude)
- 加入 keep-alive 並指定 aliveInclude 來保存目前 step 之前的所有表單組件
最後來驗證一下結果是否如預期呈現。首先,只要點選上一步就會回到前一步驟並且保留原始資料;若點選繼續時,下個步驟的表單不會有殘存先前填寫過的資料。沒錯這就是我們要的效果!
參考資訊
希望此篇文章可以幫助到需要的人
若內容有誤或有其他建議請不吝留言給筆者喔 !