olp中的todolist的实现
OLP项目todolist功能实现
#tech / dev / project
#type / howto
#status / seed
olp中的todolist的实现
目标
在 OLP 项目中实现完整的待办事项(Todo List)功能,支持:
- 任务的创建、编辑、完成、删除(CRUD)
- 任务状态管理(待办 / 进行中 / 已完成)
- 任务优先级与截止日期
- 数据持久化与跨设备同步
前置条件
- OLP 项目已初始化,前端框架(Vue3)已搭建
- 状态管理库已集成(Pinia)
- 后端 API 或本地存储方案已就绪
- 了解 Vue3 Composition API 基本用法
技术方案
整体架构
Todo 组件 (Vue3 SFC) <--> Pinia Store (状态管理) <--> API / DB (持久化)
数据结构
interface Todo {
id: string // UUID
title: string // 任务标题
description?: string // 任务描述
status: 'todo' | 'in_progress' | 'done'
priority: 'low' | 'medium' | 'high'
dueDate?: string // ISO 日期
createdAt: string
updatedAt: string
tags?: string[]
}
步骤
1. 定义数据结构与类型
创建 types/todo.ts,定义 Todo 接口和相关枚举类型。确保类型覆盖所有业务场景,包括状态流转和优先级排序。
2. 组件拆分
按职责拆分为以下组件:
| 组件 | 职责 |
|---|---|
TodoList.vue | 列表容器,负责数据获取与渲染 |
TodoItem.vue | 单条任务展示,支持状态切换 |
TodoForm.vue | 创建/编辑表单 |
TodoFilter.vue | 筛选与排序控制 |
3. 实现增删改查
Store 层(Pinia):
// stores/todo.ts
export const useTodoStore = defineStore('todo', () => {
const todos = ref<Todo[]>([])
async function fetchTodos() { /* 从 API 加载 */ }
async function addTodo(data: Partial<Todo>) { /* 创建 */ }
async function updateTodo(id: string, data: Partial<Todo>) { /* 更新 */ }
async function deleteTodo(id: string) { /* 删除 */ }
async function toggleStatus(id: string) { /* 切换完成状态 */ }
// 计算属性
const sortedByPriority = computed(() =>
[...todos.value].sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority])
)
return { todos, fetchTodos, addTodo, updateTodo, deleteTodo, toggleStatus, sortedByPriority }
})
4. 数据持久化
两种方案按需选择:
- 后端 API:RESTful 接口,适合多设备同步场景
- 本地存储:IndexedDB(Dexie.js),适合离线优先场景
// 混合方案:本地优先 + 后台同步
async function saveWithSync(todo: Todo) {
await saveToLocal(todo) // 立即写入本地
await syncToServer(todo) // 后台同步到服务端
}
5. 状态同步
- 使用 Pinia 订阅(
$subscribe)监听状态变化 - 跨组件通信通过 Store 共享状态
- 多标签页同步使用
BroadcastChannelAPI
验证
- 能创建新任务,填写标题、描述、优先级、截止日期
- 能修改任务状态(todo -> in_progress -> done)
- 能编辑和删除已有任务
- 刷新页面后数据不丢失(持久化生效)
- 按优先级/截止日期排序正确
- 筛选功能正常(按状态、优先级过滤)
常见问题
Q: 任务列表刷新后数据丢失?
检查持久化逻辑是否在组件卸载或状态变更时触发。Pinia 的 persist 插件可自动持久化到 localStorage。
Q: 大量任务时列表卡顿?
使用虚拟滚动(如 vue-virtual-scroller)只渲染可视区域的列表项。同时在 Store 层做分页加载。
Q: 多人协作时任务冲突?
采用乐观锁(版本号)或 last-write-win 策略。复杂场景考虑 CRDT 方案(如 Yjs)。