vue單頁面應用刷新網頁後vuex的state數據丟失的解決方案

最近在用vue寫pc端項目,用vuex來做全局的狀態管理, 發現當刷新網頁後,保存在vuex實例store裏的數據會丟失。

1. 產生原因

其實很簡單,因爲store裏的數據是保存在運行內存中的,當頁面刷新時,頁面會重新加載vue實例,store裏面的數據就會被重新賦值。

2. 解決思路

  1. 一種是state裏的數據全部是通過請求來觸發actionmutation來改變

  2. 一種是將state裏的數據保存一份到本地存儲(localStoragesessionStoragecookie)中

很顯然,第一種方案基本不可行,除非項目很小或者vuex存儲的數據很少。而第二種可以保證刷新頁面數據不丟失且易於讀取。

3. 解決過程

  1. 首先得選擇合適的客戶端存儲

    localStorage是永久存儲在本地,除非你主動去刪除;

    sessionStorage是存儲到當前頁面關閉爲止;

    cookie則根據你設置的有效時間來存儲,但缺點是不能儲存大數據且不易讀取。

    我選擇的是sessionStorage,選擇的原因vue是單頁面應用,操作都是在一個頁面跳轉路由,另一個原因是sessionStorage可以保證打開頁面時sessionStorage的數據爲空,而如果是localStorage則會讀取上一次打開頁面的數據。

  2. 然後是怎麼用sessionStorage來保存state裏的數據。

    第一種方案

    由於state裏的數據是響應式,所以sessionStorage存儲也要跟隨變化。又由於vuex規定所有state裏數據必須通過mutation方法來修改,所以第一種方案就是mutation修改state的同時修改sessionStorage對應存儲的屬性

    第二種方案

    第一種方案確實可以解決問題,但這種方法很明顯讓人覺得怪異,都這樣了,那不如直接用sessionStorage來做狀態管理。

    那怎麼才能不用每次修改state時同時也要修改sessionStorage呢?這時我們可以換一個思路,因爲我們是只有在刷新頁面時纔會丟失state裏的數據,那有沒有辦法在點擊頁面刷新時先將state數據保存到sessionStorage,然後才真正刷新頁面?

    當然有,beforeunload這個事件在頁面刷新時先觸發的。那這個事件應該在哪裏觸發呢?我們總不能每個頁面都監聽這個事件,所以我選擇放在app.vue這個入口組件中,這樣就可以保證每次刷新頁面都可以觸發。

    具體的代碼如下:

    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))
        })
      }
    }

    參考文章
    vue單頁應用如何在頁面刷新時保留狀態數據
    解決vuex在頁面刷新後數據被清除的問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章