先说结论:我折腾过的效率工具加起来能装满两屏,最后还是回到了最土的办法——自己写一个单文件 HTML 工作台。一个文件,双击打开就用,不用登录、不用联网、不用担心哪天服务下线。
为什么放弃那些现成的?三个理由:一是数据在别人服务器上,说关就关;二是功能太满,我 90% 的按钮半年没点过;三是导出麻烦,想拿到自己的数据还得开会员。
结构就三层,别搞复杂
我的工作台只有三个模块:待办、打卡、记账。文件结构也简单,一个 HTML 里塞三块:
<div id="app">
<section id="today"></section> <!-- 今天要处理 -->
<section id="todo"></section> <!-- 待办清单 -->
<section id="habit"></section> <!-- 习惯打卡 -->
<section id="bill"></section> <!-- 收支记账 -->
</div>
CSS 和 JS 全部写在同一个文件里,<style> 和 <script> 内联。别引 CDN,别引图标库——我吃过这个亏,把 HTML 存到本地以后图标全变方块,因为库加载不出来了。
数据存 localStorage,够用了
就一行 API,读写都极其简单:
// 存
localStorage.setItem('my_workspace_todo', JSON.stringify(todos));
// 读
const todos = JSON.parse(localStorage.getItem('my_workspace_todo') || '[]');
有人担心清缓存就没了。确实,所以我在页面上固定放了「导出 JSON」和「导入恢复」两个按钮,每周导出一次丢网盘,比什么自动同步都稳。
最容易踩的坑:函数互相调用
这个真的值得单独说。我第一版写完,点一下日历整个页面就卡死,查了半天发现是渲染日历的函数里调了渲染列表的函数,而列表渲染又回头调日历渲染,直接无限递归。
后来的做法是只留一个统一刷新入口:
function refreshAll() {
renderToday();
renderTodo();
renderHabit();
renderBill();
}
// 任何操作都只改数据,然后调 refreshAll(),绝不函数互调
改完之后再没崩过。这条经验我觉得比代码本身更值钱。
最后
自己写工作台最大的好处不是功能多强,是它完全按你的习惯长。我的记账就三个分类,因为我就这么花钱;我的打卡只有四个固定项,因为别的我坚持不下来。用现成工具你得适应它,自己写的它适应你。
唯一麻烦的是数据存哪,本地存储换台电脑就空了,只能靠导出导入
不用框架反而好维护,改一行存一下,刷新就出效果,不用等构建
单文件这个思路真的可以。我那个工作台一开始上 Vue,光依赖装了半天,后来发现根本用不上