场景
经常在网页编辑写文章的人,可能都会遇到过这种场景:手滑了,或者浏览器崩溃了,编辑的内容丢失了。
为了避免这种情况,需要加入前端缓存功能。
思路
自动缓存可以做得很复杂,比如加一个缓存草稿箱、加一个版本系统等等,这些对于黑白梦这样简单的博客来说,就显得有些过度设计了。
最后经过讨论,博客使用了一个最简单的缓存方案。
- 新增场景:保存一份缓存数据,作为新增数据
- 编辑场景:本地缓存增加一个时间戳标记,与文章 update_time 进行对比,如果缓存比文章更新,则覆盖
- 文章保存后,清除缓存
实现
使用 ant-design 的 Form 组件,监听值改变事件,进行 handleAutoSave 自动缓存设置。
<Form
initialValues={getInitialValues()}
onValuesChange={(values) => handleAutoSave()}
>
</Form>
利用 lodash 的节流工具,编写一个自动保存函数,将所有值存入 localStorage 即可。
import { throttle } from 'lodash';
const handleAutoSave = throttle(() => {
const values = form.getFieldsValue();
localStorage.setItem(
LOCAL_KEY,
JSON.stringify({
...values,
_localTimestramp: +new Date(),
}),
);
}, 5000);
当进入页面时,通过 getInitialValues 方法获取值。
const getInitialValues = () => {
const defaultData = tempRecord || {};
const localDataStr = localStorage.getItem(LOCAL_KEY);
const localData = localDataStr ? JSON.parse(localDataStr) : null;
if (localData && localData._localTimestramp && localData._localTimestramp) {
const lastAutoSavedTimestramp = localData._localTimestramp;
// 新增,或缓存修改时间比文章修改时间更新
if (
isAdd ||
(tempRecord &&
tempRecord.update_time &&
lastAutoSavedTimestramp > +new Date(tempRecord.update_time))
) {
return localData;
}
}
return defaultData;
};
保存成功后,删除缓存,即可避免影响下次的新增或编辑。
const handleSave = (values: Store) => {
localStorage.removeItem(LOCAL_KEY);
onFinish({
...values,
status: PostStatus.isPublished,
publish_time:
isAdd || (tempRecord && tempRecord.status === PostStatus.isPublished)
? parseTime(new Date())
: undefined,
});
};