文章编辑时的前端自动缓存功能思路与实现

场景

经常在网页编辑写文章的人,可能都会遇到过这种场景:手滑了,或者浏览器崩溃了,编辑的内容丢失了。

为了避免这种情况,需要加入前端缓存功能。

思路

自动缓存可以做得很复杂,比如加一个缓存草稿箱、加一个版本系统等等,这些对于黑白梦这样简单的博客来说,就显得有些过度设计了。

最后经过讨论,博客使用了一个最简单的缓存方案。

  • 新增场景:保存一份缓存数据,作为新增数据
  • 编辑场景:本地缓存增加一个时间戳标记,与文章 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,
  });
};
本文收录于专栏
一些博客建设的记录