学习进度表:把清单变成能打勾的表
这一页是真能打勾的。勾完之后刷新、切页、明天再来,进度都还在——因为勾选状态存在你自己浏览器的
localStorage里,不上传任何服务器,也没有账号。前提是同一台电脑、同一个浏览器。换设备、清缓存、开无痕窗口都会是空的。
已完成 0 / 6 项 · 0%
⛏️ 数据挖掘入门 0 / 6
一、怎么用它才有效
- 每周固定看一次,不要天天勾。进度条爬得太慢会让人焦虑,一周一次刚好能看到台阶。
- 哪一条打不上勾,就回哪一课。比如"手算支持度/置信度/提升度"勾不动,就回关联规则把 5 张小票那道手算题重做一遍。
- 别追求 100%。"能说清监督与无监督的分界"这类条目,允许自己第二次重读后才真正勾上;那才是这张表的价值。
二、原理:这一页为什么能"记住"你勾了什么
整件事没有后端、没有数据库,只有三行思路:
text
页面加载 → onMounted 里读 localStorage → 把勾选状态填回去
你打一个勾 → 组件状态变化 → watch 捕获 → 写回 localStorage对应到 docs/.vitepress/theme/components/ProgressList.vue 里的两段代码:
js
onMounted(() => { // 只能在浏览器里读,构建时没有 localStorage
const raw = window.localStorage.getItem('learn-dm:progress:v1')
if (raw) checked.value = JSON.parse(raw) || {}
ready.value = true
})
watch(checked, (val) => { // 状态一变就写回,实现"记住"
if (!ready.value) return
window.localStorage.setItem('learn-dm:progress:v1', JSON.stringify(val))
}, { deep: true })这里有一个静态站点特有的坑:VitePress 在构建时会在 Node 里把每个页面渲染成 HTML(SSR),那时根本没有 window 和 localStorage。所以在 <script setup> 顶层直接写 localStorage.getItem(...) 会让构建直接崩掉;必须放进 onMounted,因为那个钩子只在浏览器里执行。
ready 这个标志位的用处也在这里:首屏渲染时状态必须是"全都没勾"(和服务端渲染的 HTML 一致),等挂载完成后再把本地进度填进去,避免水合告警。
三、去浏览器里验证
- 勾几条,然后按
F12→ Application → 左侧 Local Storage → 选本站域名,你会看到一条 key:learn-dm:progress:v1,值是一串 JSON。这就是"网站把东西存在你电脑上"的现场。 - 直接在 DevTools 里双击那个值,把某一条从
true改成false,刷新页面——对应的勾会消失。客户端存储的一切都是用户说了算(这也是为什么权限判断永远不能放在前端)。 - 切到别的课再切回来,勾选依然在:数据不在页面里,而在浏览器里。
💡 动手实验 1:打开 Application → Local Storage,找到
learn-dm:progress:v1,右键删除它,刷新——进度清零。这就是"清空记录"按钮背后实际发生的事。💡 动手实验 2:给组件加一条你自己的验收项。打开
ProgressList.vue,在items: [ ... ]数组里加一行带引号的字符串,保存后本地预览,清单里就多了一条——改数据不用碰模板,这就是"数据驱动视图"。
四、小结
text
勾选状态 → 组件里的 ref (页面内唯一真相)
持久化 → localStorage (只在你本机,不上传)
读的时机 → onMounted (SSR 阶段没有 window,顶层读会崩)
写的时机 → watch + deep (状态一变就写回)
安全提醒 → 前端存储全可伪造 (权限校验必须在服务端)一句话:这张表是给你自己看的仪表盘,不是给别人看的成绩单。 勾满了不代表学会了,勾不动就说明还有课要回去重看——它的作用是让你知道下一步该点哪里。