Vuex 實際使用中的一點心得 —— 一刷新就沒了
問題
在開發中,有一些全局數據,比如用戶數據,系統數據等。這些數據很多組件中都會使用,我們當然可以每次使用的時候都去請求,但是出於程序員的“潔癖”、“摳”等等優點,還是希望一次請求,到處使用。
這時候很自然的想到存儲在 localStorage
中,但是有個問題是,這些數據可能會變,如果沒能及時同步的話,就會用到不正確的數據,即使做了數據同步,但是 localStorage
中的數據不是響應式的,不能自動更新使用到這些數據的地方。這時候就想要開始使用 vuex 了。
但是在使用 vuex 的時候也遇到很多問題,比如,“一刷新就沒啦”:
-
vuex
的數據是存儲在瀏覽器維護的內存中,頁面刷新會重新初始化,簡單的說,就是沒了。 -
localStorage
的數據是存儲在瀏覽器維護的一個簡單數據庫裏面,在本地文件中存儲,所以可以“持久化”存在。
所以“一刷新就沒啦”是很正常的,雖然現在很少需要用戶去刷新頁面,但是如果一刷新,數據沒了,頁面報錯了,這也是無法接受的!
解決
比如:請求數據的接口都在 src/api
下面,其中用戶相關的接口在 user.js
中;
然後在 store 下有個 userInfo.js
的 module,用來存儲用戶數據以供全局使用(關於 vuex 模塊化可以參看官方文檔):
store
|- modules
|- userInfo.js
|- index.js
userInfo.js
state
, mutations
, actions
:
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
組件中去處理。
然後在組件內使用 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
中的數據還沒有取回來,它的值是還是初始值,假如這個初始值是 null
,undefined
,那麽讀取 user.age
肯定會報錯。最簡單的辦法就是初始值設置為 {}
一個空對象(mounted
中的判斷方式要調整)當然也可以在 computed
中進行判斷處理。
現在,可以愉快的使用 vuex 了!
以上是自己在開發中填了坑之後的一點點心得,歡迎大家指點!
原文地址:https://segmentfault.com/a/1190000016709931
Vuex 實際使用中的一點心得 —— 一刷新就沒了