vuex頁面重新整理資料丟失的解決辦法

醉前端發表於2019-03-07

在vue專案中用vuex來做全域性的狀態管理, 發現當重新整理網頁後,儲存在vuex例項store裡的資料會丟失。

原因:

因為store裡的資料是儲存在執行記憶體中的,當頁面重新整理時,頁面會重新載入vue例項,store裡面的資料就會被重新賦值初始化

解決思路:

將state的資料儲存在localstorage、sessionstorage或cookie中(三者的區別),這樣即可保證頁面重新整理資料不丟失且易於讀取。

  1. localStorage: localStorage的生命週期是永久的,關閉頁面或瀏覽器之後localStorage中的資料也不會消失。localStorage除非主動刪除資料,否則資料永遠不會消失。
  2. sessionStorage:sessionStorage的生命週期是在僅在當前會話下有效。sessionStorage引入了一個“瀏覽器視窗”的概念,sessionStorage是在同源的視窗中始終存在的資料。只要這個瀏覽器視窗沒有關閉,即使重新整理頁面或者進入同源另一個頁面,資料依然存在。但是sessionStorage在關閉了瀏覽器視窗後就會被銷燬。同時獨立的開啟同一個視窗同一個頁面,sessionStorage也是不一樣的。
  3. cookie:cookie生命期為只在設定的cookie過期時間之前一直有效,即使視窗或瀏覽器關閉。 存放資料大小為4K左右,有個數限制(各瀏覽器不同),一般不能超過20個。缺點是不能儲存大資料且不易讀取。

由於vue是單頁面應用,操作都是在一個頁面跳轉路由,因此sessionStorage較為合適,原因如下:

  1. sessionStorage可以保證開啟頁面時sessionStorage的資料為空;
  2. 每次開啟頁面localStorage儲存著上一次開啟頁面的資料,因此需要清空之前的資料。

vuex中state資料的修改必須通過mutation方法進行修改,因此mutation修改state的同時需要修改sessionstorage,問題倒是可以解決但是感覺很麻煩,state中有很多資料,很多mutation修改state就要很多次sessionstorage進行修改,既然如此直接用sessionstorage解決不就行了,為何還要用vuex多此一舉呢? vuex的資料在每次頁面重新整理時丟失,是否可以在頁面重新整理前再將資料儲存到sessionstorage中呢,是可以的,beforeunload事件可以在頁面重新整理前觸發,但是在每個頁面中監聽beforeunload事件感覺也不太合適,那麼最好的監聽該事件的地方就在app.vue中。

  1. 在app.vue的created方法中讀取sessionstorage中的資料儲存在store中,此時用vuex.store的replaceState方法,替換store的根狀態
  2. 在beforeunload方法中將store.state儲存到sessionstorage中。

程式碼如下:

export default {
  name: 'App',
  created () {
    //在頁面載入時讀取sessionStorage裡的狀態資訊
    if (sessionStorage.getItem("store") ) {
        this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
    } 

    //在頁面重新整理時將vuex裡的資訊儲存到sessionStorage裡
    window.addEventListener("beforeunload",()=>{
        sessionStorage.setItem("store",JSON.stringify(this.$store.state))
    })
  }
}
複製程式碼

相關文章