Vuex 實際使用中的一點心得 —— 一刷新就沒了

問題

在開發中,有一些全局數據,好比用戶數據,系統數據等。這些數據不少組件中都會使用,咱們固然能夠每次使用的時候都去請求,可是出於程序員的「潔癖」、「摳」等等優勢,仍是但願一次請求,處處使用。javascript

這時候很天然的想到存儲在 localStorage 中,可是有個問題是,這些數據可能會變,若是沒能及時同步的話,就會用到不正確的數據,即便作了數據同步,可是 localStorage 中的數據不是響應式的,不能自動更新使用到這些數據的地方。這時候就想要開始使用 vuex 了。html

可是在使用 vuex 的時候也遇到不少問題,好比,「一刷新就沒啦」:vue

  • vuex 的數據是存儲在瀏覽器維護的內存中,頁面刷新會從新初始化,簡單的說,就是沒了。
  • localStorage 的數據是存儲在瀏覽器維護的一個簡單數據庫裏面,在本地文件中存儲,因此能夠「持久化」存在。

因此「一刷新就沒啦」是很正常的,雖然如今不多須要用戶去刷新頁面,可是若是一刷新,數據沒了,頁面報錯了,這也是沒法接受的!java

解決

好比:請求數據的接口都在 src/api 下面,其中用戶相關的接口在 user.js中;
而後在 store 下有個 userInfo.js 的 module,用來存儲用戶數據以供全局使用(關於 vuex 模塊化能夠參看官方文檔):程序員

store
 |- modules
      |- userInfo.js
 |- index.js

userInfo.js中定義了 state, mutations, actionsvuex

import { getUserInfo } from '@/api/user';

const state = {
  user: null // 注意這裏給的初始值是 null
}

const mutations = {
  setUserinfo (state, params) {
    state.user = params.user;
    localStorage.user = JSON.stringify(state.user); // 能夠順手存入 localStorage 中
  }
}

const actions = {
  async userinfo ({ commit }) {
    let ret = await getUserInfo();
    if (ret.data.retInt) { // 假如請求的數據成功返回
      commit('setUserinfo', {user: ret.data.retRes});
    }
  }
}

export default {
  state,
  mutations,
  actions
}

能夠在組件內 mounted 的時候判斷 state.userInfo.user 是否存在,若是不存在,立刻請求數據並設置到store中:數據庫

mounted () {
  if (!this.$store.state.userInfo.user) {
    this.$store.dispatch('userinfo');
  }
}

固然,這個判斷並請求的時機不必定要放在當前組件內,對於全局數據,能夠在App.vue組件中去處理。api

而後在組件內使用 store 中的數據,能夠經過 computed 屬性:瀏覽器

computed: {
  userInfo () {
    return this.$store.state.userInfo.user;
  }
}

使用 computed 屬性的好處就是數據緩存和響應式,詳細的能夠參看官方文檔關於 computed 屬性的介紹。緩存

注意

假如,如今組件中中只須要使用到用戶的 age 屬性,你可能會這麼寫:

computed: {
  userAge () {
    return this.$store.state.userInfo.user.age;
  }
}

而後,刷新頁面,你就可能看到紅紅的一大片報錯。

緣由是,user 中的數據是異步請求來的,在組件渲染過程當中使用 computed 的時候,user 中的數據尚未取回來,它的值是仍是初始值,假如這個初始值是 nullundefined,那麼讀取 user.age 確定會報錯。最簡單的辦法就是初始值設置爲 {} 一個空對象(mounted中的判斷方式要調整)固然也能夠在 computed 中進行判斷處理。

如今,能夠愉快的使用 vuex 了!

以上是本身在開發中填了坑以後的一點點心得,歡迎你們指點!

相關文章
相關標籤/搜索