"学了JavaScript这么久,我居然还在写计算器?" —— 这就像学了三年做菜只会煮方便面。今天,我们要用LocalStorage+数据可视化,开发一个既实用又炫酷的待办事项应用,让你的学习成果真正"看得见"!
一、项目亮点:为什么选择这个项目?
1.1 技能综合训练场
// 本项目涵盖:
- DOM操作(增删改查)
- 事件处理(点击、拖拽)
- 本地存储(LocalStorage)
- 数据可视化(Chart.js)
- 模块化开发(ES6模块)
1.2 最终效果预览
✅ 添加/删除任务
✅ 任务分类管理
✅ 完成状态切换
✅ 数据持久化存储
✅ 可视化统计图表
二、项目骨架:HTML结构设计
2.1 基础结构代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>智能待办清单 | 数据可视化版</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="app-container">
<header class="app-header">
<h1>我的智能待办</h1>
<div class="stats-display">
<span id="completed-count">0</span>/<span id="total-count">0</span>
<div class="progress-bar"></div>
</div>
</header>
<div class="input-area">
<input type="text" id="task-input" placeholder="添加新任务...">
<select id="category-select">
<option value="work">工作</option>
<option value="study">学习</option>
<option value="life">生活</option>
</select>
<button id="add-btn">+</button>
</div>
<div class="task-list-container">
<ul id="task-list"></ul>
</div>
<div class="visualization-section">
<canvas id="task-chart"></canvas>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script type="module" src="app.js"></script>
</body>
</html>
三、CSS设计:美观实用的界面
3.1 关键样式实现
/* 任务项动画效果 */
.task-item {
transition: all 0.3s ease;
transform-origin: left;
}
.task-item-enter {
opacity: 0;
transform: scaleX(0);
}
.task-item-enter-active {
opacity: 1;
transform: scaleX(1);
}
/* 进度条动态效果 */
.progress-bar {
height: 5px;
background: linear-gradient(to right, #4CAF50 var(--progress), #ddd var(--progress));
transition: --progress 0.5s ease;
}
/* 分类颜色标识 */
.task-item[data-category="work"] {
border-left: 4px solid #FF5252;
}
.task-item[data-category="study"] {
border-left: 4px solid #2196F3;
}
.task-item[data-category="life"] {
border-left: 4px solid #4CAF50;
}
四、JavaScript核心逻辑
4.1 数据管理模块
// storage.js
const STORAGE_KEY = 'todo-vue';
export default {
fetch() {
return JSON.parse(localStorage.getItem(STORAGE_KEY) || [];
},
save(todos) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));
}
};
4.2 任务操作模块
// tasks.js
export default {
addTask(text, category) {
return {
id: Date.now(),
text,
category,
completed: false,
createdAt: new Date()
};
},
toggleComplete(todos, id) {
return todos.map(todo =>
todo.id === id ? {...todo, completed: !todo.completed} : todo
);
},
deleteTask(todos, id) {
return todos.filter(todo => todo.id !== id);
}
};
五、数据可视化实现
5.1 图表初始化
// chart.js
import Chart from 'chart.js/auto';
export function initChart(ctx) {
return new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['工作', '学习', '生活'],
datasets: [{
data: [0, 0, 0],
backgroundColor: [
'#FF5252',
'#2196F3',
'#4CAF50'
]
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom'
}
}
}
});
}
export function updateChart(chart, todos) {
const counts = {
work: 0,
study: 0,
life: 0
};
todos.forEach(todo => {
counts[todo.category]++;
});
chart.data.datasets[0].data = [
counts.work,
counts.study,
counts.life
];
chart.update();
}
六、主应用逻辑
6.1 应用初始化
// app.js
import storage from './storage.js';
import taskManager from './tasks.js';
import { initChart, updateChart } from './chart.js';
class TodoApp {
constructor() {
this.todos = [];
this.chart = null;
this.initElements();
this.initChart();
this.loadTasks();
this.bindEvents();
}
initElements() {
this.$taskInput = document.getElementById('task-input');
this.$addBtn = document.getElementById('add-btn');
this.$categorySelect = document.getElementById('category-select');
this.$taskList = document.getElementById('task-list');
this.$completedCount = document.getElementById('completed-count');
this.$totalCount = document.getElementById('total-count');
this.$progressBar = document.querySelector('.progress-bar');
}
initChart() {
const ctx = document.getElementById('task-chart');
this.chart = initChart(ctx);
}
// ...其他方法
}
new TodoApp();
6.2 任务渲染与更新
// app.js 继续
renderTasks() {
this.$taskList.innerHTML = '';
this.todos.forEach(todo => {
const $li = document.createElement('li');
$li.className = `task-item ${todo.completed ? 'completed' : ''}`;
$li.dataset.id = todo.id;
$li.dataset.category = todo.category;
$li.innerHTML = `
<input type="checkbox" ${todo.completed ? 'checked' : ''}>
<span class="task-text">${todo.text}</span>
<button class="delete-btn">×</button>
<span class="task-category">${this.getCategoryName(todo.category)}</span>
`;
this.$taskList.appendChild($li);
});
this.updateStats();
updateChart(this.chart, this.todos);
}
updateStats() {
const total = this.todos.length;
const completed = this.todos.filter(todo => todo.completed).length;
const progress = total > 0 ? (completed / total) * 100 : 0;
this.$completedCount.textContent = completed;
this.$totalCount.textContent = total;
this.$progressBar.style.setProperty('--progress', `${progress}%`);
}
七、完整项目开发流程
7.1 分步实现计划
Day 1:基础HTML/CSS框架搭建
Day 2:实现任务添加/删除功能
Day 3:接入LocalStorage持久化
Day 4:添加数据可视化图表
Day 5:优化交互和动画效果
7.2 项目目录结构
todo-app/
├── index.html
├── styles/
│ ├── main.css
│ ├── animations.css
├── js/
│ ├── app.js # 主入口
│ ├── storage.js # 数据持久化
│ ├── tasks.js # 任务管理
│ ├── chart.js # 可视化模块
├── README.md
八、高级功能扩展
8.1 拖拽排序实现
// 在TodoApp类中添加
setupDragAndDrop() {
new Sortable(this.$taskList, {
animation: 150,
onEnd: () => {
// 更新任务顺序
const newTodos = [...this.todos];
// ...重新排序逻辑
this.saveTasks(newTodos);
}
});
}
8.2 任务搜索过滤
addSearchFunction() {
const $searchInput = document.createElement('input');
$searchInput.type = 'text';
$searchInput.placeholder = '搜索任务...';
$searchInput.addEventListener('input', (e) => {
const keyword = e.target.value.toLowerCase();
const filtered = this.todos.filter(todo =>
todo.text.toLowerCase().includes(keyword)
);
this.renderFilteredTasks(filtered);
});
document.querySelector('.input-area').prepend($searchInput);
}
九、项目部署与分享
9.1 使用GitHub Pages
# 初始化Git仓库
git init
git add .
git commit -m "初始提交"
# 创建GitHub仓库并推送
git remote add origin 你的仓库地址
git push -u origin main
# 开启GitHub Pages
# 设置 → Pages → 选择main分支
9.2 添加PWA支持(可选)
// 添加manifest.json
{
"name": "智能待办清单",
"short_name": "TodoApp",
"start_url": ".",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#4CAF50"
}
// 注册Service Worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js');
});
}
结语:从TodoList到全栈开发
这个项目只是起点!尝试添加更多功能:
用户账户系统(Firebase)
多设备同步(WebSocket)
语音添加任务(Web Speech API)
思考题:
如何实现任务到期提醒功能?
怎样优化大量任务时的性能?
如何让图表支持时间维度统计?
欢迎在评论区提交你的作品链接,我会挑选最有创意的3个项目进行深度点评!