页面刷新数据丢失
在vue中data、vuex store等都数据都是在内存当中的,页面一旦刷新,这些数据就会丢失(或者说被重置为初始值),在某些时候很影响用户体验。
缓存,恢复
要想使数据刷新不丢失,就得监听页面刷新事件,在刷新前将数据缓存到本地存储,页面刷新后再将数据从本地存储恢复。目前较普遍的做法是类似这样:
created() {
if (sessionStorage.getItem("store")) {
this.$store.replaceState(
Object.assign(
{},
this.$store.state,
JSON.parse(sessionStorage.getItem("store"))
)
);
}
window.addEventListener(
"beforeunload",()=>{
sessionStorage.setItem("store",JSON.stringify(this.$store.state));
});
}
这样做是直接将一整个store保存到本地,但是很多时候我们需要保存到本地的只是一些关键性数据,这样做缺少灵活性,而且对于那些并不想放在vuex中的数据极不友好。
改进:dataCache.ts
基于上面将数据缓存到本地存储然后页面加载时恢复的思想,我对上面的方法做了一些改进:
let caches: Record<string, { [index: string]: unknown }> = {};
let isFirst = false;
let baseId = 0;
const generateId = () => baseId++;
export default {
register(data: { [index: string]: unknown }, id?: string, ...propertyKeys: PropertyKey[]): number | string {
if (id === undefined) {
id = (generateId()).toString();
} else {
const nid = Number(id);
if (!isNaN(nid)) {
id += '_' + generateId();
}
}
const hasId = Reflect.has(caches, id);
if (isFirst && hasId) {
throw new Error('Duplicate id:\'' + id + '\'');
}
else if (hasId) {
const cache = Reflect.get(caches, id as PropertyKey);
if (cache instanceof Array) {
for (let i = 0; i < cache.length; i++) {
data[i] = cache[i];
}
} else {
const keys = propertyKeys.length < 1 ? Reflect.ownKeys(cache) : propertyKeys;
for (const key of keys) {
Reflect.set(data, key, Reflect.get(cache, key));
}
}
}
Reflect.set(caches, id, data);
return id;
},
init(itemKey: string): void {
const jsonString = sessionStorage.getItem(itemKey);
if (jsonString === null) {
isFirst = true;
} else {
caches = JSON.parse(jsonString);
}
window.addEventListener("beforeunload", () => {
sessionStorage.setItem(itemKey, JSON.stringify(caches));
});
}
}
用法
第一步:初始化
将上述代码保存到一个文件名为 dataSessionCache.js
的文件里,
然后在App.vue的created钩子中调用 init 函数进行初始化,需要提供一个itemName:
import dc from "./ts/dataCache";
export default {
created() {
dc.init('data-caches');
},
......
};
第二步:注册
对于vue组件中的数据
对于vue组件中的数据例如data,将需要缓存的数据写到一个对象里面,然后再created钩子中进行注册,例如:
import dc from "@/js/dataCache.ts";
export default {
data: () => ({
cached: {
num : 134,
str: 'str'
......
}
......
}),
created(){
sc.register(this.$data.cached);
}
};
对于VueX store
对于vuex store中的数据也可以用类似的方法:
export default new Vuex.Store({
state: {
cached: {
key: 'data'
}
......
},
......
})
import dsc from "@/js/dataCache.ts";
export default {
created() {
dsc.init('data-caches');
dsc.register(this.$store.state.cached);
},
......
};
缓存对象的非全部属性
register
的原型是register(id, obj, ...propertyKeys)
,第三个参数的作用是指定需要进行缓存的属性,如果propertyKeys
为空则会缓存其全部属性。例如,当我们想 在不改变原有代码的情况下 缓存一个单文本组件的部分data时,可以这样写:
export default {
data: () => ({
a:1,
b:'b'
}),
created() {
dsc.register('this.data,undefined,'a');
},
......
}
好处
- 在页面刷新前后进行数据的保存/恢复工作,性能开销少
- 对原有代码仅需少量修改,或者根本不需要修改原有代码
- 简单易用,灵活方便,初始化、注册两步就OK,并且可以灵活的指定需要缓存的数据
git仓库
https://gitee.com/szw-yunie/data-session-cache.js
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)