2、vuex頁面刷新數據不保留,解決方法(轉)


今天這個問題又跟頁面的刷新有一定的關系,雖然說跟頁面刷新的關系不大,但確實頁面刷新引起的這一個問題。

場景:

VueX里存儲了 this.$store.state.PV這樣一個變量,這個變量是在app.vue里通過接口獲取然后存儲在vueX里的,在路由activity.vue中,我們需要用到這個變量,並且通過這個變量的值來控制路由頁面里某一段dom元素的顯示與否。

這個需求這樣描述起來,是很好實現的。於是我就簡單寫了幾段代碼,很簡單輕松的實現了這個需求:

//acitity.vue

Dom結構

1535440033903920.png

Created生命周期

1535440050354798.png

我只需要在created生命周期里面,給posVersion這個變量賦值成this.$store.state.PV即可。

至此,這個需求看上去很“完美”的完成,沒有任何問題。

直到。。。 。。。

BUG****場景:

直到測試的同學告訴我,首次進入路由,posVersion這個值為true的時候,dom元素正常顯示,當用戶F5刷新整個頁面的時候,本應該繼續顯示的dom元素卻不見了。

我復現了這個BUG,在created里面console.log(this.$store.state.PV),卻輸出了一個空。但是如果單純刷新路由的話,dom元素還是可以正常顯示的。

這是什么鬼呢到底?

在解決這個問題之前,我們先了解幾個概念:

什么是VueX?

Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。在我看來 vuex 就是把需要共享的變量全部存儲在一個對象里面,然后將這個對象放在頂層組件中供其他組件使用,它是另一種意義上的變量提升。

**
**

**
** 路由刷新

路由刷新是無刷新跳轉,表面看起來就像是一個app應用,表現效果就像你寫的 tab 選項卡,所有的數據都還存在內存里,頁面是無重載的。

**
**

**
**

F5****頁面刷新

F5刷新做了什么事呢,重新載入頁面,銷毀之前所有的數據。

所以,這個bug出現的問題就很好理解了,F5頁面刷新,頁面銷毀之前的資源,重新請求,因此寫在生命周期里的vuex數據是重新初始化,無法獲取的,這也就是為什么會打印出空的原因。

那么既然知道問題的原因了?應該怎么處理這個問題。

解決思路1:

Localstorage 這是很容易想到的方法。將this.$store.state.PV存入到緩存里之后,然后監聽頁面重載事件,如果頁面重新載入了,那就從緩存里讀取數據,然后賦值,這樣我們的dom元素就又可愛的回到了文檔中間。

這個方法可以解決這個問題。但是如果需要用到localstorage的話,我完全可以讓我的蒙蒙小伙伴在取到pv的值的時候直接存到緩存里,然后我直接用就可以,完全就不能出現這個問題,而且就算我自己存的話,也是相對繁瑣的過程。(本方法未考慮接口返回慢的情況,請杠精少年不要太杠,不然下班跟我去搬磚)

PASS!

解決方法2:

我重新閱讀了一下vue的官方文檔,然后發現了這樣一段話:

1535440078300434.png

在此之前我曾經想過watch方法來監聽this.pvVersion這個變量,但是在頁面重載的時候watch方法也是重新進行計算加載的,所以我們可以選擇計算屬性這個方法來嘗試解決這個問題,並且官方文檔給出的解釋當中也提到了緩存,也就是如果有緩存的情況下computed會優先使用緩存,於是我在activity.vue里寫下來computed

1535440085839415.png

我懷着忐忑的心情,去手動刷新了頁面,結果,本應該顯示出來的dom元素,果然很給面子的顯示了出來。

Computed屬性的優點我試着來總結一下:

1. 純響應式,computed里面所用到的data一旦改變,整個computed的方法就回重新計算這個屬性值

2. 計算結果會被緩存起來,方便下次使用,如果下次調用的時候,其中的數據沒有發生變化,則不會重新計算。

所以我們要善用computed屬性去解決實際開發

本文轉載於http://www.speedcode.cn/ArticleDetail?id=99

注: 實際使用時當vuex值變化時,F5刷新頁面,vuex數據重置為初始狀態,所以還是要用到localStorage或sessionStorage或cookie


## 我實際用到的

一、補充本地存儲 localStorage

在App.vue中使用

created(){
    //在頁面加載時讀取localStorage里的狀態信息
    localStorage.getItem("userMsg") && this.$store.replaceState(Object.assign(this.$store.state,JSON.parse(localStorage.getItem("userMsg"))));
    
    //在頁面刷新時將vuex里的信息保存到localStorage里
    window.addEventListener("beforeunload",()=>{
        localStorage.setItem("userMsg",JSON.stringify(this.$store.state))
    })
  }

二、插件vuex-persistedstate

npm install vuex-persistedstate  --save
引入及配置

在store下的index.js中

import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
  // ...
  plugins: [createPersistedState()]
})

store
store

存儲到sessionStorage(cookie與localStore一樣):

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import user from './modules/user'
import createPersistedState from "vuex-persistedstate" // vuex-persistedstate默認持久化所有state,指定需要持久化的state
Vue.use(Vuex)

export default new Vuex.Store({
  modules: { user },
  getters,
  plugins: [
    createPersistedState({
      storage: window.sessionStorage
    })
  ]
})

vuex-persistedstate默認持久化所有state,指定需要持久化的state,配置如下:
plugins后面加數組可以配置多個

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import user from './modules/user'
import createPersistedState from "vuex-persistedstate" // vuex-persistedstate默認持久化所有state,指定需要持久化的state
Vue.use(Vuex)

export default new Vuex.Store({
  modules: { user },
  getters,
  plugins: [
    createPersistedState({
      storage: window.sessionStorage,
      reducer(val) {
          return {
          // 只儲存state中的user
          user: val.user
        }
    }
    })
  ]
})


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM