You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
307 lines
6.3 KiB
307 lines
6.3 KiB
|
2 weeks ago
|
# API 快速参考卡片
|
||
|
|
|
||
|
|
## 📋 一页纸速查表
|
||
|
|
|
||
|
|
### 项目文件对应关系
|
||
|
|
|
||
|
|
| 文件 | 作用 | 修改频率 |
|
||
|
|
|-----|------|--------|
|
||
|
|
| `src/api/index.ts` | axios 配置 + 拦截器 | 很少 |
|
||
|
|
| `src/api/auth.ts` | API 接口定义 | 经常 |
|
||
|
|
| `src/stores/auth.ts` | 认证状态管理 | 偶尔 |
|
||
|
|
| `src/views/LoginView.vue` | 登录页面 | 偶尔 |
|
||
|
|
| `.env.development` | 开发环境 API 地址 | 很少 |
|
||
|
|
| `.env.production` | 生产环境 API 地址 | 很少 |
|
||
|
|
|
||
|
|
### 工作流程简图
|
||
|
|
|
||
|
|
```
|
||
|
|
前端组件
|
||
|
|
↓
|
||
|
|
import { loginApi } from '@/api/auth'
|
||
|
|
↓
|
||
|
|
await loginApi({ username, password })
|
||
|
|
↓
|
||
|
|
axios instance (请求拦截器添加 token)
|
||
|
|
↓
|
||
|
|
POST /api/auth/login
|
||
|
|
↓
|
||
|
|
后端返回 JSON
|
||
|
|
↓
|
||
|
|
axios instance (响应拦截器提取 data)
|
||
|
|
↓
|
||
|
|
return response.data
|
||
|
|
↓
|
||
|
|
前端接收数据
|
||
|
|
```
|
||
|
|
|
||
|
|
### 常用代码片段
|
||
|
|
|
||
|
|
**1. 登录**
|
||
|
|
```typescript
|
||
|
|
import { useAuthStore } from '@/stores/auth'
|
||
|
|
|
||
|
|
const authStore = useAuthStore()
|
||
|
|
const success = await authStore.login('admin', '123456')
|
||
|
|
```
|
||
|
|
|
||
|
|
**2. 获取当前用户**
|
||
|
|
```typescript
|
||
|
|
const authStore = useAuthStore()
|
||
|
|
console.log(authStore.user)
|
||
|
|
console.log(authStore.token)
|
||
|
|
```
|
||
|
|
|
||
|
|
**3. 登出**
|
||
|
|
```typescript
|
||
|
|
const authStore = useAuthStore()
|
||
|
|
await authStore.logout()
|
||
|
|
```
|
||
|
|
|
||
|
|
**4. 创建新 API 接口**
|
||
|
|
```typescript
|
||
|
|
// src/api/users.ts
|
||
|
|
import http from './index'
|
||
|
|
|
||
|
|
export const getUsersApi = () => {
|
||
|
|
return http.get('/users')
|
||
|
|
}
|
||
|
|
|
||
|
|
// 组件中使用
|
||
|
|
import { getUsersApi } from '@/api/users'
|
||
|
|
const response = await getUsersApi()
|
||
|
|
```
|
||
|
|
|
||
|
|
### 后端需要的东西
|
||
|
|
|
||
|
|
**登录接口**
|
||
|
|
```
|
||
|
|
POST /api/auth/login
|
||
|
|
|
||
|
|
请求:
|
||
|
|
{
|
||
|
|
"username": "admin",
|
||
|
|
"password": "123456"
|
||
|
|
}
|
||
|
|
|
||
|
|
响应:
|
||
|
|
{
|
||
|
|
"code": 200,
|
||
|
|
"message": "登录成功",
|
||
|
|
"data": {
|
||
|
|
"token": "jwt_token_here",
|
||
|
|
"user": {
|
||
|
|
"id": "1",
|
||
|
|
"username": "admin",
|
||
|
|
"email": "admin@example.com",
|
||
|
|
"role": "admin"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**所有其他接口**
|
||
|
|
```
|
||
|
|
Authorization: Bearer <token> (自动添加)
|
||
|
|
|
||
|
|
返回格式:
|
||
|
|
{
|
||
|
|
"code": 200,
|
||
|
|
"message": "...",
|
||
|
|
"data": {...}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 调试技巧
|
||
|
|
|
||
|
|
**1. 查看网络请求**
|
||
|
|
- 打开浏览器开发者工具 (F12)
|
||
|
|
- 点击 Network 标签
|
||
|
|
- 登录看看 POST /api/auth/login 的请求和响应
|
||
|
|
|
||
|
|
**2. 查看存储的 token**
|
||
|
|
- 打开浏览器开发者工具 (F12)
|
||
|
|
- 点击 Application 标签
|
||
|
|
- 找到 LocalStorage
|
||
|
|
- 查看 `auth_token` 和 `user`
|
||
|
|
|
||
|
|
**3. 打印错误**
|
||
|
|
```typescript
|
||
|
|
try {
|
||
|
|
await loginApi(...)
|
||
|
|
} catch (error) {
|
||
|
|
console.log(error) // 查看具体错误
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 环境变量配置
|
||
|
|
|
||
|
|
**开发环境** (`.env.development`)
|
||
|
|
```
|
||
|
|
VITE_API_URL=http://localhost:3000/api
|
||
|
|
```
|
||
|
|
|
||
|
|
**生产环境** (`.env.production`)
|
||
|
|
```
|
||
|
|
VITE_API_URL=https://api.yourdomain.com/api
|
||
|
|
```
|
||
|
|
|
||
|
|
**在代码中使用**
|
||
|
|
```typescript
|
||
|
|
console.log(import.meta.env.VITE_API_URL)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 常见错误解决
|
||
|
|
|
||
|
|
| 错误 | 原因 | 解决 |
|
||
|
|
|-----|------|------|
|
||
|
|
| CORS error | 跨域问题 | 后端配置 CORS |
|
||
|
|
| 401 | token 过期 | 自动清除,跳转登录 |
|
||
|
|
| 404 | 接口不存在 | 检查后端路由 |
|
||
|
|
| 500 | 服务器错误 | 检查后端日志 |
|
||
|
|
| 网络错误 | 后端未启动 | 启动后端服务 |
|
||
|
|
|
||
|
|
### 完整登录示例
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { ref } from 'vue'
|
||
|
|
import { useRouter } from 'vue-router'
|
||
|
|
import { useAuthStore } from '@/stores/auth'
|
||
|
|
import { ElMessage } from 'element-plus'
|
||
|
|
|
||
|
|
const router = useRouter()
|
||
|
|
const authStore = useAuthStore()
|
||
|
|
const username = ref('admin')
|
||
|
|
const password = ref('123456')
|
||
|
|
const loading = ref(false)
|
||
|
|
|
||
|
|
const handleLogin = async () => {
|
||
|
|
loading.value = true
|
||
|
|
try {
|
||
|
|
// 调用异步登录
|
||
|
|
const success = await authStore.login(username.value, password.value)
|
||
|
|
if (success) {
|
||
|
|
ElMessage.success('登录成功')
|
||
|
|
router.push('/admin/dashboard')
|
||
|
|
} else {
|
||
|
|
ElMessage.error('登录失败')
|
||
|
|
}
|
||
|
|
} catch (error: any) {
|
||
|
|
ElMessage.error(error?.message || '登录错误')
|
||
|
|
} finally {
|
||
|
|
loading.value = false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<template>
|
||
|
|
<input v-model="username" type="text" placeholder="用户名" />
|
||
|
|
<input v-model="password" type="password" placeholder="密码" />
|
||
|
|
<button @click="handleLogin" :disabled="loading">
|
||
|
|
{{ loading ? '登录中...' : '登录' }}
|
||
|
|
</button>
|
||
|
|
</template>
|
||
|
|
```
|
||
|
|
|
||
|
|
### API 调用模板
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// 1. 创建接口文件 src/api/xxx.ts
|
||
|
|
import http from './index'
|
||
|
|
|
||
|
|
export interface XXXRequest {
|
||
|
|
// 请求参数
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface XXXResponse {
|
||
|
|
code: number
|
||
|
|
message: string
|
||
|
|
data: {
|
||
|
|
// 响应数据
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export const xxxApi = (params: XXXRequest): Promise<XXXResponse> => {
|
||
|
|
return http.post('/xxx', params)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. 在组件中使用
|
||
|
|
import { xxxApi } from '@/api/xxx'
|
||
|
|
|
||
|
|
const response = await xxxApi({ /* 参数 */ })
|
||
|
|
if (response.code === 200) {
|
||
|
|
// 成功处理
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### HTTP 方法速查
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// GET 请求
|
||
|
|
http.get('/users')
|
||
|
|
http.get('/users?page=1&limit=10')
|
||
|
|
http.get('/users', { params: { page: 1 } })
|
||
|
|
|
||
|
|
// POST 请求
|
||
|
|
http.post('/users', { name: 'John' })
|
||
|
|
|
||
|
|
// PUT 请求
|
||
|
|
http.put('/users/1', { name: 'Jane' })
|
||
|
|
|
||
|
|
// DELETE 请求
|
||
|
|
http.delete('/users/1')
|
||
|
|
|
||
|
|
// PATCH 请求
|
||
|
|
http.patch('/users/1', { name: 'Bob' })
|
||
|
|
```
|
||
|
|
|
||
|
|
### token 在请求中的流程
|
||
|
|
|
||
|
|
```
|
||
|
|
1. 用户登录 → token 保存到 localStorage
|
||
|
|
2. 请求拦截器检查 localStorage 中的 token
|
||
|
|
3. 如果有 token,添加到请求头:Authorization: Bearer <token>
|
||
|
|
4. 后端验证 token
|
||
|
|
5. 后端返回数据或 401 错误
|
||
|
|
6. 响应拦截器检查状态码
|
||
|
|
7. 如果 401,清除 token 并跳转登录页
|
||
|
|
```
|
||
|
|
|
||
|
|
### 测试后端接口的命令
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 测试登录
|
||
|
|
curl -X POST http://localhost:3000/api/auth/login \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"username":"admin","password":"123456"}'
|
||
|
|
|
||
|
|
# 获取响应中的 token
|
||
|
|
# 复制 token 值
|
||
|
|
|
||
|
|
# 测试其他接口(需要 token)
|
||
|
|
curl -X GET http://localhost:3000/api/users \
|
||
|
|
-H "Authorization: Bearer YOUR_TOKEN_HERE"
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🚀 快速启动清单
|
||
|
|
|
||
|
|
- [ ] 后端启动在 http://localhost:3000
|
||
|
|
- [ ] 后端实现 POST /api/auth/login 接口
|
||
|
|
- [ ] 后端返回正确的 JSON 格式
|
||
|
|
- [ ] 前端运行 `npm run dev`
|
||
|
|
- [ ] 前端 .env.development 中 VITE_API_URL 指向后端
|
||
|
|
- [ ] 打开浏览器访问 http://localhost:5173
|
||
|
|
- [ ] 输入用户名和密码登录
|
||
|
|
- [ ] 查看浏览器 Network 标签验证请求
|
||
|
|
- [ ] 检查 localStorage 中是否保存了 token
|
||
|
|
- [ ] 登录成功后跳转到仪表板
|
||
|
|
|
||
|
|
## 📞 获取帮助
|
||
|
|
|
||
|
|
1. 查看 `API_INTEGRATION_GUIDE.md` - 详细教程
|
||
|
|
2. 查看 `BACKEND_API_EXAMPLE.md` - 后端代码示例
|
||
|
|
3. 查看组件代码注释
|
||
|
|
4. 打开浏览器开发者工具查看错误
|
||
|
|
5. 检查后端日志
|