一、前言
在前端开发中,Todo List(待办事项列表) 是一个非常经典的入门项目。它涵盖了组件化思想、数据绑定、事件处理、本地存储等核心知识点,非常适合用来练习 Vue 的基本用法。
本文将带你一步步实现一个功能完整的 Vue Todo List 应用,包括:
- 添加任务
- 删除任务
- 标记任务完成状态
- 清除已完成任务
- 使用
localStorage
保存数据
通过本案例,你将掌握 Vue 开发的基本流程与常用技巧,为后续开发更复杂的项目打下坚实基础。
二、项目目标
我们要实现一个如下功能的 Todo List:
功能 | 描述 |
---|---|
添加任务 | 输入内容后点击"添加"按钮或按回车键新增任务 |
删除任务 | 点击任务右侧的删除按钮即可移除该任务 |
完成状态切换 | 点击任务文本可切换完成状态(划线显示) |
显示任务总数 | 显示当前任务总数 |
显示未完成数 | 显示未完成的任务数量 |
清除已完成任务 | 可一键清除所有已完成的任务 |
数据持久化 | 使用 localStorage 保存数据,刷新页面不丢失 |
三、技术选型
- Vue 3(支持 Composition API)
- Vue CLI 脚手架初始化项目
<script setup>
语法糖(更简洁)- HTML + CSS 布局
localStorage
实现数据持久化
四、项目结构说明
bash
vue-todo/
├── public/ # 静态资源(不参与构建)
├── src/
│ ├── App.vue # 根组件
│ ├── main.js # 入口文件
│ └── components/
│ └── TodoList.vue # 待办事项主组件
├── package.json
└── README.md
五、开发步骤详解
第一步:创建 Vue 项目
如果你还没有创建项目,可以通过 Vue CLI 快速搭建:
bash
vue create vue-todo
cd vue-todo
npm run serve
选择默认配置即可。
第二步:创建 TodoList 组件
1. 创建组件文件
在 src/components/TodoList.vue
中创建组件。
javascript
<template>
<div class="todo-container">
<h2>我的待办事项</h2>
<!-- 添加任务 -->
<div class="input-group">
<input
v-model="newTodo"
@keyup.enter="addTodo"
placeholder="输入新任务..."
class="todo-input"
/>
<button @click="addTodo" class="btn">添加</button>
</div>
<!-- 任务列表 -->
<ul class="todo-list">
<li
v-for="(todo, index) in todos"
:key="todo.id"
:class="{ completed: todo.completed }"
@click="toggleComplete(index)"
class="todo-item"
>
{{ todo.text }}
<button @click.stop="removeTodo(index)" class="delete-btn">删除</button>
</li>
</ul>
<!-- 操作按钮 -->
<div class="actions">
<p>共 {{ todos.length }} 项任务,还有 {{ remainingCount }} 项未完成</p>
<button @click="clearCompleted" class="btn">清除已完成</button>
</div>
</div>
</template>
<script setup>
import { ref, computed, watchEffect } from 'vue'
// 初始化任务数组
const todos = ref(loadFromLocalStorage())
// 新增任务
const newTodo = ref('')
function addTodo() {
const text = newTodo.value.trim()
if (text === '') return
todos.value.push({
id: Date.now(),
text,
completed: false
})
newTodo.value = ''
}
// 切换完成状态
function toggleComplete(index) {
todos.value[index].completed = !todos.value[index].completed
}
// 删除任务
function removeTodo(index) {
todos.value.splice(index, 1)
}
// 清除已完成任务
function clearCompleted() {
todos.value = todos.value.filter(todo => !todo.completed)
}
// 计算未完成任务数
const remainingCount = computed(() => {
return todos.value.filter(todo => !todo.completed).length
})
// 监听数据变化并保存到 localStorage
watchEffect(() => {
saveToLocalStorage(todos.value)
})
// 本地存储方法
function saveToLocalStorage(data) {
localStorage.setItem('todos', JSON.stringify(data))
}
function loadFromLocalStorage() {
const data = localStorage.getItem('todos')
return data ? JSON.parse(data) : []
}
</script>
<style scoped>
.todo-container {
max-width: 500px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 8px;
font-family: Arial;
}
.input-group {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.todo-input {
flex: 1;
padding: 8px;
font-size: 16px;
}
.btn {
padding: 8px 12px;
background-color: #42b983;
color: white;
border: none;
cursor: pointer;
border-radius: 4px;
}
.todo-list {
list-style: none;
padding-left: 0;
}
.todo-item {
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
position: relative;
}
.todo-item:hover .delete-btn {
display: inline-block;
}
.todo-item.completed {
text-decoration: line-through;
color: gray;
}
.delete-btn {
position: absolute;
right: 10px;
top: 10px;
display: none;
background-color: #e74c3c;
}
.actions {
margin-top: 20px;
}
</style>
第三步:在 App.vue 中引入组件
javascript
<template>
<div id="app">
<TodoList />
</div>
</template>
<script setup>
import TodoList from './components/TodoList.vue'
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
六、运行效果预览
启动项目:
bash
npm run serve
打开浏览器访问 http://localhost:8080
,你会看到一个美观且功能齐全的待办事项列表。
你可以:
- 输入任务并按下回车或点击"添加";
- 点击任务条目切换完成状态;
- 点击"删除"按钮删除任务;
- 点击"清除已完成"按钮一键清理已完成任务;
- 刷新页面后任务不会丢失。
七、功能扩展建议(进阶)
功能 | 实现建议 |
---|---|
支持编辑任务 | 在任务条目上添加"编辑"按钮,允许修改文本内容 |
支持任务分类 | 添加标签或分类字段,如"工作"、"生活"等 |
使用 Vuex/Pinia | 将状态管理抽离出来,便于大型项目维护 |
支持多人协作 | 结合 WebSocket 或 Firebase 实现实时同步 |
支持拖拽排序 | 使用第三方库如 SortableJS |
移动端适配 | 使用响应式布局优化手机端体验 |
八、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!