三招教你如何解決Vuex數(shù)據(jù)丟失問題
大家好,我是小楊,一個經(jīng)歷過Vuex數(shù)據(jù)"人間蒸發(fā)"慘案的老司機(jī)。上周還在加班趕工,第二天打開項目發(fā)現(xiàn)購物車空了?用戶登錄狀態(tài)丟了?別急!今天就用冰箱存食物的比喻,教你守住Vuex里的每一份數(shù)據(jù)!
(文末附贈【防丟代碼套餐】,直接復(fù)制就能用~)
一、數(shù)據(jù)丟失的五大案發(fā)現(xiàn)場
案發(fā)現(xiàn)場1:頁面刷新 → 冰箱斷電
// store里的數(shù)據(jù)就像斷電后的冰箱
state: {
cartItems: [] // 刷新后:空!??
}
案發(fā)現(xiàn)場2:瀏覽器隱身模式 → 冰箱沒插電
// 本地存儲無法使用
localStorage.getItem('user') // 返回null
案發(fā)現(xiàn)場3:異步操作未完成 → 外賣還沒送到就關(guān)冰箱
actions: {
async fetchUser({ commit }) {
const user = await 我.調(diào)接口() // 如果刷新頁面...
commit('SET_USER', user) // 可能永遠(yuǎn)執(zhí)行不到!
}
}
案發(fā)現(xiàn)場4:SSR hydration失敗 → 冰箱門沒關(guān)嚴(yán)
// 服務(wù)端渲染時,客戶端初始化狀態(tài)不匹配
window.__INITIAL_STATE__ = {...} // 傳輸過程中丟失
二、五道防盜門方案
方案1:本地存儲持久化(給冰箱加發(fā)電機(jī))
// store初始化時讀取
const user = JSON.parse(localStorage.getItem('user') || 'null')
const store = new Vuex.Store({
state: { user },
plugins: [
store => {
// 狀態(tài)變化時自動保存
store.subscribe((mutation, state) => {
localStorage.setItem('user', JSON.stringify(state.user))
})
}
]
})
方案2:vuex-persistedstate插件(智能保鮮膜)
npm install vuex-persistedstate
import createPersistedState from 'vuex-persistedstate'
const store = new Vuex.Store({
plugins: [
createPersistedState({
paths: ['user', 'cart'] // 只持久化指定模塊
})
]
})
方案3:會話管理(臨時小冰柜)
// 使用sessionStorage替代(標(biāo)簽頁關(guān)閉時清除)
createPersistedState({
storage: window.sessionStorage
})
方案4:防抖保存(省電模式)
let saveTimer
store.subscribe((_, state) => {
clearTimeout(saveTimer)
saveTimer = setTimeout(() => {
localStorage.setItem('store', JSON.stringify(state))
}, 1000) // 1秒防抖
})
方案5:SSR數(shù)據(jù)脫水/注水(冷鏈運(yùn)輸)
// 服務(wù)端
context.state = store.state
// 客戶端
if (window.__INITIAL_STATE__) {
store.replaceState(window.__INITIAL_STATE__)
}
三、實戰(zhàn)代碼套餐
套餐A:用戶登錄狀態(tài)保衛(wèi)戰(zhàn)
// store/modules/user.js
export default {
state: () => ({
token: null,
profile: null
}),
mutations: {
LOGIN(state, { token, profile }) {
state.token = token
state.profile = profile
// 同步保存到本地存儲
localStorage.setItem('auth', JSON.stringify({ token, profile }))
}
},
actions: {
initAuth({ commit }) {
const auth = JSON.parse(localStorage.getItem('auth'))
if (auth) commit('LOGIN', auth)
}
}
}
套餐B:購物車數(shù)據(jù)搶救方案
// store/plugins/cartPersistence.js
export default store => {
// 初始化時讀取
const savedCart = localStorage.getItem('cart')
if (savedCart) {
store.commit('cart/RESTORE_CART', JSON.parse(savedCart))
}
// 監(jiān)聽變化
store.subscribe((mutation, state) => {
if (mutation.type.startsWith('cart/')) {
localStorage.setItem('cart', JSON.stringify(state.cart.items))
}
})
}
四、避坑指南
1.敏感信息別亂存
- ? 把用戶密碼存在localStorage
- ? 只存token,及時過期
2.大體積數(shù)據(jù)要謹(jǐn)慎
// 超過5MB可能引發(fā)性能問題
localStorage.setItem('hugeData', JSON.stringify(bigData))
3.SSR的坑要注意
// 判斷是否客戶端環(huán)境
if (process.client) {
const data = localStorage.getItem('data')
}
4.隱私模式兼容方案
try {
localStorage.setItem('test', 'test')
} catch (e) {
console.warn('隱私模式禁用本地存儲')
// 降級方案:使用內(nèi)存存儲或cookie
}
五、終極解決方案:vuex-persist + 加密
import VuexPersistence from 'vuex-persist'
import SecureLS from 'secure-ls'
const ls = new SecureLS({ isCompression: false })
const vuexLocal = new VuexPersistence({
storage: {
getItem: key => ls.get(key),
setItem: (key, value) => ls.set(key, value),
removeItem: key => ls.remove(key)
},
filter: mutation =>
!mutation.type.includes('敏感操作')
})
const store = new Vuex.Store({
plugins: [vuexLocal.plugin]
})
資源大禮包
完整示例項目:github.com/xiaoyang/vuex-data-rescue
性能對比表:
| 方案 | 優(yōu)點 | 缺點 |
|---|---|---|
| localStorage | 持久化 | 5MB限制 |
| sessionStorage | 標(biāo)簽頁級隔離 | 關(guān)閉即丟失 |
| IndexedDB | 大容量 | API復(fù)雜 |
| Cookies | 自動攜帶 | 4KB限制 |
?到此這篇關(guān)于三招教你如何解決Vuex數(shù)據(jù)丟失問題的文章就介紹到這了,更多相關(guān)Vuex數(shù)據(jù)丟失解決內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+vuex+axio從后臺獲取數(shù)據(jù)存入vuex實現(xiàn)組件之間共享數(shù)據(jù)
這篇文章主要介紹了vue+vuex+axio從后臺獲取數(shù)據(jù)存入vuex,組件之間共享數(shù)據(jù),非常具有實用價值,需要的朋友可以參考下2017-04-04
vue如何使用process.env搭建自定義運(yùn)行環(huán)境
這篇文章主要介紹了vue如何使用process.env搭建自定義運(yùn)行環(huán)境,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
Vue2 使用 Echarts 創(chuàng)建圖表實例代碼
本篇文章主要介紹了Vue2 使用 Echarts 創(chuàng)建圖表實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05

