文字游戏
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

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. 检查后端日志