1. 项目概述
这个待办清单系统采用Vue3.0作为前端框架,Express作为后端服务,实现了完整的CRUD功能。我在实际开发中发现,Vue3.0的Composition API配合Express的RESTful接口,能够构建出响应迅速、结构清晰的现代化Web应用。
系统主要包含以下核心功能:
- 任务增删改查
- 任务状态标记
- 数据持久化存储
- 响应式界面交互
2. 技术栈选型分析
2.1 Vue3.0的优势考量
选择Vue3.0主要基于以下几个关键因素:
- Composition API提供了更好的代码组织方式
- 性能提升显著,打包体积减少约40%
- 更好的TypeScript支持
- 更灵活的逻辑复用方式
与Vue2.x相比,Vue3.0的响应式系统完全重写,使用Proxy替代了Object.defineProperty,这使得:
- 可以检测到属性的添加和删除
- 对数组和Map/Set的支持更好
- 性能更高,特别是在大型应用中
2.2 Express作为后端的选择理由
Express作为轻量级Node.js框架,具有以下优势:
- 中间件架构灵活
- 路由系统简单高效
- 社区生态丰富
- 学习曲线平缓
对于待办清单这类数据操作不复杂的应用,Express完全能够满足需求,同时保持代码简洁。
3. 系统架构设计
3.1 前端架构
采用典型的Vue3.0单页应用结构:
code复制src/
├── components/
│ ├── TodoList.vue
│ ├── TodoItem.vue
│ └── AddTodo.vue
├── stores/ # Pinia状态管理
├── router/ # 路由配置
├── services/ # API服务
└── App.vue
3.2 后端架构
Express采用分层设计:
code复制server/
├── controllers/
├── models/
├── routes/
├── middlewares/
└── app.js
4. 核心功能实现
4.1 前端关键代码
使用Composition API实现任务列表:
javascript复制// TodoList.vue
import { ref, onMounted } from 'vue'
import { useTodoStore } from '@/stores/todo'
export default {
setup() {
const todoStore = useTodoStore()
const newTodo = ref('')
onMounted(async () => {
await todoStore.fetchTodos()
})
const addTodo = async () => {
if (newTodo.value.trim()) {
await todoStore.addTodo(newTodo.value)
newTodo.value = ''
}
}
return { todoStore, newTodo, addTodo }
}
}
4.2 后端接口实现
Express路由示例:
javascript复制// routes/todos.js
const express = require('express')
const router = express.Router()
const Todo = require('../models/Todo')
router.get('/', async (req, res) => {
try {
const todos = await Todo.find()
res.json(todos)
} catch (err) {
res.status(500).json({ message: err.message })
}
})
router.post('/', async (req, res) => {
const todo = new Todo({
text: req.body.text,
completed: false
})
try {
const newTodo = await todo.save()
res.status(201).json(newTodo)
} catch (err) {
res.status(400).json({ message: err.message })
}
})
5. 数据持久化方案
5.1 数据库选择
使用MongoDB作为数据存储,主要因为:
- 文档型数据库适合待办事项这类非结构化数据
- 与Node.js生态集成良好
- 开发模式简单,无需预先定义schema
5.2 Mongoose模型定义
javascript复制// models/Todo.js
const mongoose = require('mongoose')
const todoSchema = new mongoose.Schema({
text: {
type: String,
required: true
},
completed: {
type: Boolean,
default: false
},
createdAt: {
type: Date,
default: Date.now
}
})
module.exports = mongoose.model('Todo', todoSchema)
6. 状态管理方案
6.1 Pinia的使用
选择Pinia而非Vuex的原因:
- 专为Vue3设计
- 更简单的API
- 更好的TypeScript支持
- 模块化设计更自然
6.2 Store实现示例
javascript复制// stores/todo.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
import todoService from '@/services/todo'
export const useTodoStore = defineStore('todo', () => {
const todos = ref([])
const loading = ref(false)
const error = ref(null)
const fetchTodos = async () => {
try {
loading.value = true
todos.value = await todoService.getAll()
} catch (err) {
error.value = err.message
} finally {
loading.value = false
}
}
const addTodo = async (text) => {
try {
const newTodo = await todoService.create(text)
todos.value.push(newTodo)
} catch (err) {
error.value = err.message
}
}
return { todos, loading, error, fetchTodos, addTodo }
})
7. 项目部署方案
7.1 前端部署
使用Vite构建:
bash复制npm run build
生成的dist目录可以部署到任意静态文件服务器,如:
- Netlify
- Vercel
- Nginx
- GitHub Pages
7.2 后端部署
推荐部署方案:
- 传统服务器:使用PM2管理Node进程
bash复制
pm2 start server.js - 云平台:如Heroku、Railway等
- 容器化:Docker部署
8. 开发中的经验总结
8.1 跨域问题解决
开发环境下配置代理:
javascript复制// vite.config.js
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
})
生产环境解决方案:
- 启用CORS中间件
- 配置Nginx反向代理
- 前后端同域部署
8.2 性能优化技巧
-
前端:
- 使用Vue的v-once指令优化静态内容
- 合理使用计算属性和watch
- 组件懒加载
-
后端:
- 添加缓存中间件
- 数据库查询优化
- 启用gzip压缩
9. 常见问题排查
9.1 数据不更新问题
可能原因及解决方案:
- 忘记调用save()方法 → 确保所有修改操作后调用save
- 响应式丢失 → 使用Vue.set或解构赋值
- 状态管理异常 → 检查Pinia的state更新逻辑
9.2 接口请求失败
排查步骤:
- 检查网络控制台,确认请求是否发出
- 查看请求头和响应状态码
- 验证后端接口是否正常工作
- 检查CORS配置
10. 项目扩展方向
- 用户认证:添加JWT认证
- 多用户支持:实现用户隔离
- 分类功能:为任务添加标签或分类
- 数据同步:实现离线编辑和在线同步
- 移动端适配:开发PWA版本
在实际开发中,我发现Vue3.0的setup语法糖能显著提升开发效率,而Express的中间件机制则让后端开发变得非常灵活。这个项目虽然不大,但涵盖了现代Web开发的许多核心概念,是学习前后端分离架构的绝佳实践。
