从零搭建一个极简任务看板:FlowBoard 的设计与实现
从零搭建一个极简任务看板:FlowBoard 的设计与实现
前言
在日常开发中,任务管理是每个开发者都绕不开的话题。市面上的工具要么太重(Jira、Trello),要么需要注册账号,要么依赖网络。有时候我们只想要一个简单的看板,能拖拽任务卡片、记录进度,仅此而已。
于是我用一个单文件 HTML 做了一个——FlowBoard,一个极简现代风格的个人任务看板。没有框架、没有构建工具、没有后端,打开浏览器就能用,刷新不丢数据。本文分享它的设计思路和实现细节。
功能一览
FlowBoard 的核心功能包括:
- 三列看板:待办(Todo)、进行中(In Progress)、已完成(Done),每列实时显示任务计数
- 任务管理:添加、编辑(双击)、删除(悬停显示 ×)任务卡片
- 拖拽移动:基于 HTML5 Drag and Drop API,卡片可在三列之间自由拖拽,目标列高亮提示
- 主题切换:深色 / 浅色一键切换,偏好自动记住
- 本地持久化:所有数据存储在浏览器 localStorage,刷新页面不丢失
- 开箱即用:首次打开预置示例任务,无需配置
技术选型:为什么是单文件?
在动手之前,我考虑过几种方案:
| 方案 | 优点 | 缺点 |
|---|---|---|
| React + Vite | 组件化、生态丰富 | 需要构建、依赖多、部署重 |
| Vue + CDN | 轻量 | 仍需引入框架运行时 |
| 纯 HTML + JS | 零依赖、即开即用 | 需要手动管理 DOM |
最终选择了纯 HTML + CSS + JS 单文件方案。理由很简单:
- 部署成本为零——一个
index.html,python3 -m http.server 8080就能跑 - 无外部依赖——不依赖任何 CDN、框架、构建工具,断网也能用
- 代码量可控——功能闭环完整,但全部代码在一个文件里,易于理解和修改
- 学习友好——对于刚接触前端的开发者,没有抽象层干扰,每一行代码都能看懂
核心实现
1. 数据模型与持久化
任务的数据结构非常简单:
// 每个任务卡片
{
id: "task-1700000000000", // 唯一 ID(时间戳生成)
title: "完成项目文档", // 任务标题
column: "todo" // 所在列:todo / doing / done
}
// 全部数据
{
tasks: [/* 任务数组 */],
theme: "light" // 主题偏好
}
持久化用 localStorage,每次数据变更时序列化写入,页面加载时反序列化恢复:
function save() {
localStorage.setItem('flowboard', JSON.stringify({
tasks: tasks,
theme: currentTheme
}));
}
function load() {
const data = JSON.parse(localStorage.getItem('flowboard') || '{}');
tasks = data.tasks || [];
currentTheme = data.theme || 'light';
}
这里有个细节:首次打开时 localStorage 为空,我预置了 4 条示例任务分散在三列,让用户第一眼就能看到看板的效果,而不是一个空页面。
2. 拖拽实现
拖拽用的是原生 HTML5 Drag and Drop API,不引入任何库。核心是三个事件:
// 卡片开始拖拽
card.addEventListener('dragstart', (e) => {
draggedTaskId = card.dataset.id;
e.dataTransfer.effectAllowed = 'move';
});
// 列允许放置
column.addEventListener('dragover', (e) => {
e.preventDefault(); // 必须 preventDefault 才能触发 drop
column.classList.add('drag-over'); // 高亮目标列
});
// 卡片放入新列
column.addEventListener('drop', (e) => {
e.preventDefault();
const taskId = draggedTaskId;
const newColumn = column.dataset.column;
moveTask(taskId, newColumn); // 更新数据 + 重新渲染 + 保存
});
dragover 里的 e.preventDefault() 是关键——不调用它,浏览器会拒绝 drop 事件。这是新手常踩的坑。
3. 毛玻璃卡片效果
FlowBoard 的视觉风格核心是毛玻璃(frosted glass)效果,用 CSS backdrop-filter 实现:
.card {
background: rgba(255, 255, 255, 0.65);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
padding: 12px 16px;
margin-bottom: 10px;
}
backdrop-filter: blur(12px) 让卡片背景产生毛玻璃模糊效果,配合半透明背景色 rgba(255,255,255,0.65),卡片浮在看板背景之上,层次感很强。
深色主题下只需切换 CSS 变量:
[data-theme="dark"] {
--bg: #1a1b26;
--card-bg: rgba(45, 48, 68, 0.6);
--text: #c0caf5;
}
4. 主题切换
主题切换通过 data-theme 属性挂在 <html> 上,CSS 用属性选择器响应:
function toggleTheme() {
currentTheme = currentTheme === 'light' ? 'dark' : 'light';
document.documentElement.setAttribute('data-theme', currentTheme);
save(); // 持久化主题偏好
}
下次打开页面时,load() 会读取保存的主题并立即设置,避免闪烁。
界面设计理念
FlowBoard 的设计遵循三个原则:
克制——主色只用一个靛蓝 #4f6df5,不堆砌色彩。按钮、高亮、拖拽提示都用这一个色,视觉统一。
留白——看板最大宽度 1100px 居中,列与列之间有间距,卡片之间有间距,不挤。
质感——毛玻璃 + 柔和阴影 + 12px 圆角,让卡片有"浮起来"的感觉,不是扁平到无聊。
本地运行也很简单:
git clone https://gitcode.com/sdf2342/flowboard.git
cd flowboard
python3 -m http.server 8080
浏览器打开 http://localhost:8080 即可。
总结
FlowBoard 证明了一件事:不是所有项目都需要 React、都需要构建工具、都需要后端。当你只需要一个简单好用的工具时,一个单文件 HTML 就能搞定,而且体验不输那些"大而全"的方案。
关键在于想清楚你真正需要什么——三列看板、拖拽、持久化,就这些。剩下的就是把这些功能用最简洁的方式实现出来。
如果你也想做一个类似的小工具,希望这篇博客能给你一些启发。完整源码已在 GitCode 开源,欢迎 Fork 和改进。
本文作品已在华为云开发者作品展览馆发布,欢迎前往体验交流。
- 点赞
- 收藏
- 关注作者
评论(0)