四、系统架构图
1. 系统架构图
scss
┌─────────────────────────────────────────────────────────┐
│ 用户浏览器 │
│ (Vue 3 + Vite) │
└────────────────┬────────────────────────────────────────┘
│
│ HTTP/WebSocket
│
┌────────────────▼────────────────────────────────────────┐
│ Nginx (可选) │
│ 反向代理/负载均衡 │
└────────────────┬────────────────────────────────────────┘
│
┌────────┴────────┐
│ │
┌───────▼──────┐ ┌──────▼────────┐
│ 前端服务 │ │ 后端服务 │
│ (Port 3000) │ │ (Port 5000) │
│ │ │ Express │
└──────────────┘ └───────┬───────┘
│
┌───────┼───────┐
│ │ │
┌───────▼──┐ ┌──▼────┐ ┌▼────────┐
│ MongoDB │ │Socket │ │ 文件存储 │
│ 数据库 │ │ IO │ │ /uploads│
└──────────┘ └───────┘ └─────────┘
2. 前端架构
目录结构
js
frontend/
├── src/
│ ├── components/ # 可复用组件
│ │ ├── admin/ # 管理后台组件
│ │ ├── AppNavbar.vue # 导航栏
│ │ ├── ChatBox.vue # 聊天框
│ │ ├── ChatList.vue # 聊天列表
│ │ ├── ProductCard.vue # 商品卡片
│ │ └── ...
│ ├── views/ # 页面组件
│ │ ├── Home.vue # 首页
│ │ ├── Login.vue # 登录页
│ │ ├── Products.vue # 商品列表
│ │ ├── ProductDetail.vue # 商品详情
│ │ ├── Chat.vue # 聊天页
│ │ ├── Admin.vue # 管理后台
│ │ └── ...
│ ├── stores/ # 状态管理
│ │ ├── user.ts # 用户状态
│ │ └── product.ts # 商品状态
│ ├── router/ # 路由配置
│ │ └── index.ts
│ ├── utils/ # 工具函数
│ │ ├── api.ts # API封装
│ │ ├── validation.ts # 表单验证
│ │ └── dateUtils.ts # 日期工具
│ ├── types/ # TypeScript类型
│ │ └── index.ts
│ ├── test/ # 测试文件
│ ├── App.vue # 根组件
│ └── main.ts # 入口文件
├── public/ # 静态资源
├── package.json
└── vite.config.ts
组件设计原则
- 单一职责:每个组件只负责一个功能
- 可复用性:通用组件抽离到components目录
- Props验证:使用TypeScript进行类型约束
- 事件命名:使用kebab-case命名自定义事件
- 样式隔离:使用scoped样式
Vue 3 核心特性深度解析
Composition API 的设计理念:
Vue 3 引入 Composition API 是为了解决 Options API 在大型项目中的几个痛点:
- 逻辑复用困难 - Options API 中相关逻辑分散在不同选项中
- 类型推导不友好 - TypeScript 支持不够完善
- 代码组织混乱 - 大组件中相关代码被迫分离
typescript
// 使用 <script setup> 语法 - 这是 Vue 3.2+ 的语法糖
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
// 1. 响应式数据 - ref 用于基本类型
// ref 会返回一个响应式的引用对象,通过 .value 访问值
const count = ref(0)
// 2. 计算属性 - 自动追踪依赖,缓存结果
// 只有当依赖的响应式数据变化时才会重新计算
const doubleCount = computed(() => count.value * 2)
// 3. 生命周期钩子 - 在 setup 中直接调用
// 相比 Options API,名称前加了 'on' 前缀
onMounted(() => {
console.log('组件已挂载')
// 这里可以进行 DOM 操作、发起 API 请求等
})
</script>
响应式系统深入理解:
Vue 3 使用 Proxy 实现响应式,相比 Vue 2 的 Object.defineProperty 有以下优势:
- 可以监听数组索引和长度变化
- 可以监听对象属性的添加和删除
- 性能更好,不需要递归遍历所有属性
typescript
// ref() - 用于基本类型的响应式
// 原理:将值包装在一个对象中,通过 .value 访问
const count = ref(0)
count.value++ // 触发响应式更新
// reactive() - 用于对象的响应式
// 原理:使用 Proxy 代理整个对象
const state = reactive({
user: { name: 'John', age: 25 },
products: []
})
state.user.name = 'Jane' // 直接修改,自动触发更新
// computed() - 计算属性
// 特点:1. 惰性求值 2. 缓存结果 3. 自动依赖追踪
const fullName = computed(() => {
console.log('计算执行') // 只在依赖变化时执行
return `${state.user.name} (${state.user.age})`
})
// watch() - 侦听器,用于执行副作用
// 可以侦听单个或多个响应式数据源
watch(count, (newVal, oldVal) => {
console.log(`count 从 ${oldVal} 变为 ${newVal}`)
// 可以在这里执行异步操作、API 调用等
})
// watchEffect() - 自动追踪依赖的侦听器
// 立即执行,自动收集依赖
watchEffect(() => {
console.log(`当前 count: ${count.value}`)
// 任何在这里使用的响应式数据变化都会触发重新执行
})
3. 后端架构
目录结构
js
backend/
├── models/ # 数据模型
│ ├── User.js # 用户模型
│ ├── Product.js # 商品模型
│ ├── Order.js # 订单模型
│ └── Message.js # 消息模型
├── routes/ # 路由处理
│ ├── auth.js # 认证路由
│ ├── products.js # 商品路由
│ ├── orders.js # 订单路由
│ ├── messages.js # 消息路由
│ ├── users.js # 用户路由
│ └── admin.js # 管理员路由
├── middleware/ # 中间件
│ ├── auth.js # 认证中间件
│ ├── admin.js # 管理员中间件
│ └── upload.js # 文件上传中间件
├── socket/ # Socket.IO处理
│ └── socketHandler.js # Socket事件处理
├── utils/ # 工具函数
│ └── helpers.js
├── scripts/ # 脚本文件
│ ├── init-admin.js # 初始化管理员
│ └── import-data.js # 导入测试数据
├── uploads/ # 文件上传目录
├── server.js # 服务器入口
├── .env # 环境变量
└── package.json
后端技术知识点
Express 框架
基础路由:
javascript
const express = require('express')
const app = express()
// 中间件
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
// 路由
app.get('/api/products', async (req, res) => {
try {
const products = await Product.find()
res.json({ success: true, data: products })
} catch (error) {
res.status(500).json({ success: false, message: error.message })
}
})
中间件系统:
javascript
// 日志中间件
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`)
next()
})
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).json({ message: '服务器错误' })
})
4. 数据库设计
数据模型关系图
js
┌─────────────┐ ┌─────────────┐
│ User │◄───────►│ Product │
│ │ 1 * │ │
│ - _id │ │ - _id │
│ - username │ │ - title │
│ - password │ │ - price │
│ - email │ │ - seller │
│ - avatar │ │ - status │
│ - role │ └─────────────┘
│ - followers│ │
│ - following│ │ *
│ - favorites│ │
└─────────────┘ │
│ 1 │
│ │
│ * │ 1
┌─────────────┐ ┌─────────────┐
│ Message │ │ Order │
│ │ │ │
│ - _id │ │ - _id │
│ - sender │ │ - buyer │
│ - receiver │ │ - seller │
│ - content │ │ - product │
│ - isRead │ │ - status │
└─────────────┘ │ - amount │
└─────────────┘
为什么选择 MongoDB:
MongoDB 是一个 NoSQL 文档数据库,特别适合本项目的原因:
- 灵活的数据模型 - 文档结构可以随需求变化,不需要预定义严格的表结构
- 嵌套文档支持 - 可以直接存储复杂的嵌套数据(如商品评论、用户关注列表)
- 水平扩展 - 支持分片,易于扩展
- JSON 格式 - 与 JavaScript 天然契合
- 高性能 - 对于读多写少的场景性能优秀
Mongoose Schema 设计原理:
Mongoose 是 MongoDB 的 ODM(Object Document Mapping),提供了数据建模、验证、查询构建等功能。
五、 快速启动指南 🚀
前置要求
- Node.js >= 16.0.0
- pnpm >= 8.0.0
- MongoDB(需要启动服务)
三步启动项目
第一步:安装依赖
bash
pnpm install
第二步:导入测试数据
bash
pnpm run import
输出示例:
markdown
✅ MongoDB连接成功
✅ 数据库已清空
✅ 创建了 5 个用户
✅ 创建了 15 个商品
✅ 创建了 5 个订单
✅ 创建了 7 条消息
✅ 数据导入完成!
📊 数据统计:
- 用户: 5
- 商品: 15
- 订单: 5
- 消息: 7
💡 测试账号:
管理员: admin / admin123
普通用户: 张三 / 123456
普通用户: 李四 / 123456
第三步:启动开发服务器
bash
pnpm run dev
这会同时启动:
- 🎨 前端开发服务器:http://localhost:3000
- 🔧 后端API服务器:http://localhost:5000