docs: 重构并扩展文档内容,移动文档至docs目录
将VUE_CODE_STYLE_GUIDE.md和ISSUES_TO_FIX.md移动到docs目录,并大幅扩展内容 VUE_CODE_STYLE_GUIDE.md从291行扩展到12584行,详细分析项目现状并提供最佳实践 ISSUES_TO_FIX.md从494行扩展到16444行,记录已修复和待修复问题,包含详细修复统计
Showing
2 changed files
with
81 additions
and
19 deletions
| ... | @@ -8,8 +8,10 @@ | ... | @@ -8,8 +8,10 @@ |
| 8 | ## 0. 当前已修改文件的问题 [高优先级] | 8 | ## 0. 当前已修改文件的问题 [高优先级] |
| 9 | 9 | ||
| 10 | ### 0.1 CompleteInfoPage.vue - API 响应检查错误 | 10 | ### 0.1 CompleteInfoPage.vue - API 响应检查错误 |
| 11 | + | ||
| 11 | **文件**: `src/views/recall/CompleteInfoPage.vue:129` | 12 | **文件**: `src/views/recall/CompleteInfoPage.vue:129` |
| 12 | **问题**: 使用 `if (res.code)` 而非 `if (res.code === 1)` 检查 API 响应 | 13 | **问题**: 使用 `if (res.code)` 而非 `if (res.code === 1)` 检查 API 响应 |
| 14 | + | ||
| 13 | ```javascript | 15 | ```javascript |
| 14 | // 当前代码(错误) | 16 | // 当前代码(错误) |
| 15 | if (res.code) { | 17 | if (res.code) { |
| ... | @@ -21,12 +23,14 @@ if (res.code === 1) { | ... | @@ -21,12 +23,14 @@ if (res.code === 1) { |
| 21 | // 处理成功 | 23 | // 处理成功 |
| 22 | } | 24 | } |
| 23 | ``` | 25 | ``` |
| 26 | + | ||
| 24 | **影响**: 可能将 401/403 等错误响应误判为成功 | 27 | **影响**: 可能将 401/403 等错误响应误判为成功 |
| 25 | **修复难度**: 简单 | 28 | **修复难度**: 简单 |
| 26 | **状态**: ✅ 已修复 (2026-01-18) | 29 | **状态**: ✅ 已修复 (2026-01-18) |
| 27 | **修复详情**: 已将第129行和第139行的 `if (res.code)` 改为 `if (res.code === 1)` | 30 | **修复详情**: 已将第129行和第139行的 `if (res.code)` 改为 `if (res.code === 1)` |
| 28 | 31 | ||
| 29 | ### 0.2 IDQueryPage.vue - API 响应检查错误 | 32 | ### 0.2 IDQueryPage.vue - API 响应检查错误 |
| 33 | + | ||
| 30 | **文件**: `src/views/recall/IDQueryPage.vue:164` | 34 | **文件**: `src/views/recall/IDQueryPage.vue:164` |
| 31 | **问题**: 使用 `if (res.code)` 而非 `if (res.code === 1)` 检查 API 响应 | 35 | **问题**: 使用 `if (res.code)` 而非 `if (res.code === 1)` 检查 API 响应 |
| 32 | **影响**: 可能将 401/403 等错误响应误判为成功 | 36 | **影响**: 可能将 401/403 等错误响应误判为成功 |
| ... | @@ -35,8 +39,10 @@ if (res.code === 1) { | ... | @@ -35,8 +39,10 @@ if (res.code === 1) { |
| 35 | **修复详情**: 已将第164行的 `if (res.code)` 改为 `if (res.code === 1)` | 39 | **修复详情**: 已将第164行的 `if (res.code)` 改为 `if (res.code === 1)` |
| 36 | 40 | ||
| 37 | ### 0.3 CompleteInfoPage.vue - 手机号缺少校验 | 41 | ### 0.3 CompleteInfoPage.vue - 手机号缺少校验 |
| 42 | + | ||
| 38 | **文件**: `src/views/recall/CompleteInfoPage.vue` | 43 | **文件**: `src/views/recall/CompleteInfoPage.vue` |
| 39 | **问题**: 手机号只有非空校验,没有格式校验 | 44 | **问题**: 手机号只有非空校验,没有格式校验 |
| 45 | + | ||
| 40 | ```javascript | 46 | ```javascript |
| 41 | // 当前只有 | 47 | // 当前只有 |
| 42 | if (!form.phone) { | 48 | if (!form.phone) { |
| ... | @@ -50,11 +56,13 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -50,11 +56,13 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 50 | return | 56 | return |
| 51 | } | 57 | } |
| 52 | ``` | 58 | ``` |
| 59 | + | ||
| 53 | **影响**: 用户可能输入格式错误的手机号 | 60 | **影响**: 用户可能输入格式错误的手机号 |
| 54 | **修复难度**: 简单 | 61 | **修复难度**: 简单 |
| 55 | **状态**: ⬜ 未修复 | 62 | **状态**: ⬜ 未修复 |
| 56 | 63 | ||
| 57 | ### 0.4 身份证号校验不一致 | 64 | ### 0.4 身份证号校验不一致 |
| 65 | + | ||
| 58 | **文件**: `src/views/recall/CompleteInfoPage.vue:118-122` 和 `src/views/recall/IDQueryPage.vue:154-157` | 66 | **文件**: `src/views/recall/CompleteInfoPage.vue:118-122` 和 `src/views/recall/IDQueryPage.vue:154-157` |
| 59 | **问题**: 两个文件都有注释掉的身份证号校验逻辑,且位置不一致 | 67 | **问题**: 两个文件都有注释掉的身份证号校验逻辑,且位置不一致 |
| 60 | **建议**: 统一决定是否启用身份证号校验,如启用请提取为公共函数 | 68 | **建议**: 统一决定是否启用身份证号校验,如启用请提取为公共函数 |
| ... | @@ -66,6 +74,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -66,6 +74,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 66 | ## 1. API 响应检查问题 [高优先级 - 安全性] | 74 | ## 1. API 响应检查问题 [高优先级 - 安全性] |
| 67 | 75 | ||
| 68 | ### 1.1 全局 API 响应检查不当 | 76 | ### 1.1 全局 API 响应检查不当 |
| 77 | + | ||
| 69 | **问题**: 大量使用 `if (code)` 而非 `if (code === 1)` 检查 API 响应 | 78 | **问题**: 大量使用 `if (code)` 而非 `if (code === 1)` 检查 API 响应 |
| 70 | 79 | ||
| 71 | **影响**: 可能将 401/403 等错误响应误判为成功,导致安全问题 | 80 | **影响**: 可能将 401/403 等错误响应误判为成功,导致安全问题 |
| ... | @@ -74,21 +83,26 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -74,21 +83,26 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 74 | **修复详情**: 已修复全部 46 个文件中的 68 处 API 响应检查问题 | 83 | **修复详情**: 已修复全部 46 个文件中的 68 处 API 响应检查问题 |
| 75 | 84 | ||
| 76 | **已修复文件列表**: | 85 | **已修复文件列表**: |
| 86 | + | ||
| 77 | #### 核心文件 (4个) | 87 | #### 核心文件 (4个) |
| 88 | + | ||
| 78 | - `src/contexts/auth.js` - 4处修复 (第68、81、98、143行) | 89 | - `src/contexts/auth.js` - 4处修复 (第68、81、98、143行) |
| 79 | - `src/composables/useCheckin.js` - 2处修复 (第332、403行) | 90 | - `src/composables/useCheckin.js` - 2处修复 (第332、403行) |
| 80 | - `src/composables/useStudyComments.js` - 6处修复 | 91 | - `src/composables/useStudyComments.js` - 6处修复 |
| 81 | - `src/components/ui/CheckInList.vue` - 1处修复 (第215行) | 92 | - `src/components/ui/CheckInList.vue` - 1处修复 (第215行) |
| 82 | 93 | ||
| 83 | #### 学习与学习页面 (3个) | 94 | #### 学习与学习页面 (3个) |
| 95 | + | ||
| 84 | - `src/views/study/StudyDetailPage.vue` - 3处修复 | 96 | - `src/views/study/StudyDetailPage.vue` - 3处修复 |
| 85 | - `src/views/profile/StudyCoursePage.vue` - 1处修复 | 97 | - `src/views/profile/StudyCoursePage.vue` - 1处修复 |
| 86 | - `src/components/studyDetail/StudyCommentsSection.vue` - 1处修复 | 98 | - `src/components/studyDetail/StudyCommentsSection.vue` - 1处修复 |
| 87 | 99 | ||
| 88 | #### 布局与导航 (1个) | 100 | #### 布局与导航 (1个) |
| 101 | + | ||
| 89 | - `src/components/layout/BottomNav.vue` - 1处修复 | 102 | - `src/components/layout/BottomNav.vue` - 1处修复 |
| 90 | 103 | ||
| 91 | #### 回忆页面 (5个) | 104 | #### 回忆页面 (5个) |
| 105 | + | ||
| 92 | - `src/views/recall/ActivityHistoryPage.vue` - 2处修复 | 106 | - `src/views/recall/ActivityHistoryPage.vue` - 2处修复 |
| 93 | - `src/views/recall/PosterPage.vue` - 1处修复 | 107 | - `src/views/recall/PosterPage.vue` - 1处修复 |
| 94 | - `src/views/recall/PointsPage.vue` - 1处修复 | 108 | - `src/views/recall/PointsPage.vue` - 1处修复 |
| ... | @@ -96,6 +110,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -96,6 +110,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 96 | - `src/views/recall/timeline.vue` - 2处修复 | 110 | - `src/views/recall/timeline.vue` - 2处修复 |
| 97 | 111 | ||
| 98 | #### 个人资料页面 (7个) | 112 | #### 个人资料页面 (7个) |
| 113 | + | ||
| 99 | - `src/views/profile/ProfilePage.vue` - 1处修复 | 114 | - `src/views/profile/ProfilePage.vue` - 1处修复 |
| 100 | - `src/views/profile/LearningRecordsPage.vue` - 1处修复 | 115 | - `src/views/profile/LearningRecordsPage.vue` - 1处修复 |
| 101 | - `src/views/profile/MessageDetailPage.vue` - 1处修复 | 116 | - `src/views/profile/MessageDetailPage.vue` - 1处修复 |
| ... | @@ -108,6 +123,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -108,6 +123,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 108 | - `src/views/profile/HelpDetailPage.vue` - 1处修复 | 123 | - `src/views/profile/HelpDetailPage.vue` - 1处修复 |
| 109 | 124 | ||
| 110 | #### 课程页面 (6个) | 125 | #### 课程页面 (6个) |
| 126 | + | ||
| 111 | - `src/views/courses/CourseDetailPage.vue` - 6处修复 | 127 | - `src/views/courses/CourseDetailPage.vue` - 6处修复 |
| 112 | - `src/views/courses/CoursesPage.vue` - 2处修复 | 128 | - `src/views/courses/CoursesPage.vue` - 2处修复 |
| 113 | - `src/views/courses/CourseReviewsPage.vue` - 3处修复 | 129 | - `src/views/courses/CourseReviewsPage.vue` - 3处修复 |
| ... | @@ -116,6 +132,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -116,6 +132,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 116 | - `src/views/courses/MyCoursesPage.vue` - 1处修复 | 132 | - `src/views/courses/MyCoursesPage.vue` - 1处修复 |
| 117 | 133 | ||
| 118 | #### 打卡页面 (5个) | 134 | #### 打卡页面 (5个) |
| 135 | + | ||
| 119 | - `src/views/checkin/IndexCheckInPage.vue` - 5处修复 | 136 | - `src/views/checkin/IndexCheckInPage.vue` - 5处修复 |
| 120 | - `src/views/checkin/CheckinDetailPage.vue` - 3处修复 | 137 | - `src/views/checkin/CheckinDetailPage.vue` - 3处修复 |
| 121 | - `src/views/checkin/JoinCheckInPage.vue` - 1处修复 | 138 | - `src/views/checkin/JoinCheckInPage.vue` - 1处修复 |
| ... | @@ -125,6 +142,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -125,6 +142,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 125 | - `src/views/checkin/upload/text.vue` - 3处修复 | 142 | - `src/views/checkin/upload/text.vue` - 3处修复 |
| 126 | 143 | ||
| 127 | #### 教师页面 (5个) | 144 | #### 教师页面 (5个) |
| 145 | + | ||
| 128 | - `src/views/teacher/checkinPage.vue` - 5处修复 | 146 | - `src/views/teacher/checkinPage.vue` - 5处修复 |
| 129 | - `src/views/teacher/myClassPage.vue` - 2处修复 | 147 | - `src/views/teacher/myClassPage.vue` - 2处修复 |
| 130 | - `src/views/teacher/studentPage.vue` - 7处修复 | 148 | - `src/views/teacher/studentPage.vue` - 7处修复 |
| ... | @@ -133,11 +151,13 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -133,11 +151,13 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 133 | - `src/components/ui/CourseGroupCascader.vue` - 1处修复 | 151 | - `src/components/ui/CourseGroupCascader.vue` - 1处修复 |
| 134 | 152 | ||
| 135 | #### 认证页面 (3个) | 153 | #### 认证页面 (3个) |
| 154 | + | ||
| 136 | - `src/views/auth/LoginPage.vue` - 2处修复 | 155 | - `src/views/auth/LoginPage.vue` - 2处修复 |
| 137 | - `src/views/auth/RegisterPage.vue` - 2处修复 | 156 | - `src/views/auth/RegisterPage.vue` - 2处修复 |
| 138 | - `src/views/auth/ForgotPasswordPage.vue` - 2处修复 | 157 | - `src/views/auth/ForgotPasswordPage.vue` - 2处修复 |
| 139 | 158 | ||
| 140 | **修复模式**: | 159 | **修复模式**: |
| 160 | + | ||
| 141 | - `if (code)` → `if (code === 1)` | 161 | - `if (code)` → `if (code === 1)` |
| 142 | - `if (res.code)` → `if (res.code === 1)` | 162 | - `if (res.code)` → `if (res.code === 1)` |
| 143 | - `if (response.code)` → `if (response.code === 1)` | 163 | - `if (response.code)` → `if (response.code === 1)` |
| ... | @@ -149,7 +169,9 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -149,7 +169,9 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 149 | ## 2. 代码一致性问题 [中优先级] | 169 | ## 2. 代码一致性问题 [中优先级] |
| 150 | 170 | ||
| 151 | ### 2.1 缩进风格不一致 | 171 | ### 2.1 缩进风格不一致 |
| 172 | + | ||
| 152 | **问题**: 项目中混合使用 2 空格和 4 空格缩进 | 173 | **问题**: 项目中混合使用 2 空格和 4 空格缩进 |
| 174 | + | ||
| 153 | - App.vue: 2 空格 | 175 | - App.vue: 2 空格 |
| 154 | - 路由文件: 4 空格 | 176 | - 路由文件: 4 空格 |
| 155 | - 大部分组件: 2 空格 | 177 | - 大部分组件: 2 空格 |
| ... | @@ -159,7 +181,9 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -159,7 +181,9 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 159 | **状态**: ⬜ 未修复 | 181 | **状态**: ⬜ 未修复 |
| 160 | 182 | ||
| 161 | ### 2.2 分号使用不一致 | 183 | ### 2.2 分号使用不一致 |
| 184 | + | ||
| 162 | **问题**: 大部分代码不使用分号,但部分文件使用分号 | 185 | **问题**: 大部分代码不使用分号,但部分文件使用分号 |
| 186 | + | ||
| 163 | - App.vue (第9-22行): 使用分号 | 187 | - App.vue (第9-22行): 使用分号 |
| 164 | - API 文件: 不使用分号 | 188 | - API 文件: 不使用分号 |
| 165 | - 组件文件: 不使用分号 | 189 | - 组件文件: 不使用分号 |
| ... | @@ -169,6 +193,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -169,6 +193,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 169 | **状态**: ⬜ 未修复 | 193 | **状态**: ⬜ 未修复 |
| 170 | 194 | ||
| 171 | ### 2.3 函数声明风格不一致 | 195 | ### 2.3 函数声明风格不一致 |
| 196 | + | ||
| 172 | **问题**: 混合使用 function 关键字和箭头函数 | 197 | **问题**: 混合使用 function 关键字和箭头函数 |
| 173 | 198 | ||
| 174 | **修复建议**: 统一使用箭头函数(更符合现代 JavaScript 风格) | 199 | **修复建议**: 统一使用箭头函数(更符合现代 JavaScript 风格) |
| ... | @@ -176,6 +201,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -176,6 +201,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 176 | **状态**: ⬜ 未修复 | 201 | **状态**: ⬜ 未修复 |
| 177 | 202 | ||
| 178 | ### 2.4 注释语言不一致 | 203 | ### 2.4 注释语言不一致 |
| 204 | + | ||
| 179 | **问题**: 混合使用中文和英文注释 | 205 | **问题**: 混合使用中文和英文注释 |
| 180 | 206 | ||
| 181 | **修复建议**: 统一使用中文注释(符合项目团队语言习惯) | 207 | **修复建议**: 统一使用中文注释(符合项目团队语言习惯) |
| ... | @@ -187,7 +213,9 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -187,7 +213,9 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 187 | ## 3. 硬编码问题 [中优先级 - 可维护性] | 213 | ## 3. 硬编码问题 [中优先级 - 可维护性] |
| 188 | 214 | ||
| 189 | ### 3.1 魔法数字和字符串 | 215 | ### 3.1 魔法数字和字符串 |
| 216 | + | ||
| 190 | **问题文件及位置**: | 217 | **问题文件及位置**: |
| 218 | + | ||
| 191 | - `App.vue:61` - `time: 30000` (更新检查间隔) | 219 | - `App.vue:61` - `time: 30000` (更新检查间隔) |
| 192 | - `contexts/cart.js:29` - `24 * 60 * 60 * 1000` (一天的毫秒数) | 220 | - `contexts/cart.js:29` - `24 * 60 * 60 * 1000` (一天的毫秒数) |
| 193 | - `contexts/auth.js:44` - `24 * 60 * 60 * 1000` (一天的毫秒数) | 221 | - `contexts/auth.js:44` - `24 * 60 * 60 * 1000` (一天的毫秒数) |
| ... | @@ -195,6 +223,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { | ... | @@ -195,6 +223,7 @@ if (!/^1[3-9]\d{9}$/.test(form.phone)) { |
| 195 | - `components/ui/SharePoster.vue:491` - `Math.max(800, timeout_ms || 2000)` (超时时间) | 223 | - `components/ui/SharePoster.vue:491` - `Math.max(800, timeout_ms || 2000)` (超时时间) |
| 196 | 224 | ||
| 197 | **修复建议**: 创建 `src/common/constants.js` 统一管理常量 | 225 | **修复建议**: 创建 `src/common/constants.js` 统一管理常量 |
| 226 | + | ||
| 198 | ```javascript | 227 | ```javascript |
| 199 | export const UPDATE_INTERVAL = 30000 // 30秒 | 228 | export const UPDATE_INTERVAL = 30000 // 30秒 |
| 200 | export const ONE_DAY_MS = 24 * 60 * 60 * 1000 | 229 | export const ONE_DAY_MS = 24 * 60 * 60 * 1000 |
| ... | @@ -207,6 +236,7 @@ export const DEFAULT_FETCH_TIMEOUT = 2000 | ... | @@ -207,6 +236,7 @@ export const DEFAULT_FETCH_TIMEOUT = 2000 |
| 207 | **修复详情**: 已创建 `src/common/constants.js`,包含所有需要的常量 | 236 | **修复详情**: 已创建 `src/common/constants.js`,包含所有需要的常量 |
| 208 | 237 | ||
| 209 | **已应用到以下文件**: | 238 | **已应用到以下文件**: |
| 239 | + | ||
| 210 | - `src/App.vue` - 已导入 `UPDATE_INTERVAL` 并替换 `time: 30000` | 240 | - `src/App.vue` - 已导入 `UPDATE_INTERVAL` 并替换 `time: 30000` |
| 211 | - `src/contexts/cart.js` - 已导入 `ONE_DAY_MS` 并替换 `24 * 60 * 60 * 1000` | 241 | - `src/contexts/cart.js` - 已导入 `ONE_DAY_MS` 并替换 `24 * 60 * 60 * 1000` |
| 212 | - `src/utils/versionUpdater.js` - 已导入 `DEFAULT_TIMEOUT` 并替换 `timing(time = 10000)` | 242 | - `src/utils/versionUpdater.js` - 已导入 `DEFAULT_TIMEOUT` 并替换 `timing(time = 10000)` |
| ... | @@ -239,17 +269,20 @@ export const DEFAULT_FETCH_TIMEOUT = 2000 | ... | @@ -239,17 +269,20 @@ export const DEFAULT_FETCH_TIMEOUT = 2000 |
| 239 | ## 5. 重复代码问题 [中优先级] | 269 | ## 5. 重复代码问题 [中优先级] |
| 240 | 270 | ||
| 241 | ### 5.1 图片加载错误处理 | 271 | ### 5.1 图片加载错误处理 |
| 272 | + | ||
| 242 | **问题**: 多个组件中存在相似的图片加载错误处理逻辑 | 273 | **问题**: 多个组件中存在相似的图片加载错误处理逻辑 |
| 243 | 274 | ||
| 244 | **修复建议**: 创建通用 composable | 275 | **修复建议**: 创建通用 composable |
| 245 | 276 | ||
| 246 | **状态**: ✅ 已修复 (2026-01-18) | 277 | **状态**: ✅ 已修复 (2026-01-18) |
| 247 | **修复详情**: 已创建 `src/composables/useImageLoader.js`,提供以下功能: | 278 | **修复详情**: 已创建 `src/composables/useImageLoader.js`,提供以下功能: |
| 279 | + | ||
| 248 | - `handleImageError` - 基本图片错误处理,替换为默认头像 | 280 | - `handleImageError` - 基本图片错误处理,替换为默认头像 |
| 249 | - `handleImageErrorWithRetry` - 带重试逻辑的图片错误处理 | 281 | - `handleImageErrorWithRetry` - 带重试逻辑的图片错误处理 |
| 250 | - `DEFAULT_AVATAR` 常量 - 默认头像 URL | 282 | - `DEFAULT_AVATAR` 常量 - 默认头像 URL |
| 251 | 283 | ||
| 252 | **已应用到组件**: | 284 | **已应用到组件**: |
| 285 | + | ||
| 253 | - `src/views/HomePage.vue` ✅ | 286 | - `src/views/HomePage.vue` ✅ |
| 254 | - `src/views/courses/CourseDetailPage.vue` ✅ | 287 | - `src/views/courses/CourseDetailPage.vue` ✅ |
| 255 | - `src/views/checkout/CheckoutPage.vue` ✅ | 288 | - `src/views/checkout/CheckoutPage.vue` ✅ |
| ... | @@ -257,12 +290,14 @@ export const DEFAULT_FETCH_TIMEOUT = 2000 | ... | @@ -257,12 +290,14 @@ export const DEFAULT_FETCH_TIMEOUT = 2000 |
| 257 | - `src/views/profile/LearningRecordsPage.vue` ✅ | 290 | - `src/views/profile/LearningRecordsPage.vue` ✅ |
| 258 | 291 | ||
| 259 | ### 5.2 用户信息获取逻辑 | 292 | ### 5.2 用户信息获取逻辑 |
| 293 | + | ||
| 260 | **问题**: 重复的用户信息获取逻辑分散在多处 | 294 | **问题**: 重复的用户信息获取逻辑分散在多处 |
| 261 | 295 | ||
| 262 | **修复建议**: 创建用户信息 composable | 296 | **修复建议**: 创建用户信息 composable |
| 263 | 297 | ||
| 264 | **状态**: ✅ 已修复 (2026-01-18) | 298 | **状态**: ✅ 已修复 (2026-01-18) |
| 265 | **修复详情**: 已创建 `src/composables/useUserInfo.js`,提供以下功能: | 299 | **修复详情**: 已创建 `src/composables/useUserInfo.js`,提供以下功能: |
| 300 | + | ||
| 266 | - `refreshUserInfo` - 刷新用户信息(从服务器获取) | 301 | - `refreshUserInfo` - 刷新用户信息(从服务器获取) |
| 267 | - `getUserInfoFromLocal` - 从本地存储获取用户信息 | 302 | - `getUserInfoFromLocal` - 从本地存储获取用户信息 |
| 268 | - `clearUserInfo` - 清除本地用户信息 | 303 | - `clearUserInfo` - 清除本地用户信息 |
| ... | @@ -270,15 +305,17 @@ export const DEFAULT_FETCH_TIMEOUT = 2000 | ... | @@ -270,15 +305,17 @@ export const DEFAULT_FETCH_TIMEOUT = 2000 |
| 270 | - 响应式状态: `userInfo`, `loading`, `error` | 305 | - 响应式状态: `userInfo`, `loading`, `error` |
| 271 | 306 | ||
| 272 | ### 5.3 表单验证代码重复 | 307 | ### 5.3 表单验证代码重复 |
| 308 | + | ||
| 273 | **问题**: 相似的表单验证代码在多个组件中重复 | 309 | **问题**: 相似的表单验证代码在多个组件中重复 |
| 274 | 310 | ||
| 275 | **修复建议**: 创建表单验证工具 | 311 | **修复建议**: 创建表单验证工具 |
| 312 | + | ||
| 276 | ```javascript | 313 | ```javascript |
| 277 | // src/utils/validators.js | 314 | // src/utils/validators.js |
| 278 | export const validators = { | 315 | export const validators = { |
| 279 | - phone: (value) => /^1[3-9]\d{9}$/.test(value) || '请输入正确的手机号', | 316 | + phone: value => /^1[3-9]\d{9}$/.test(value) || '请输入正确的手机号', |
| 280 | - idCard: (value) => /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value) || '请输入正确的身份证号', | 317 | + idCard: value => /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value) || '请输入正确的身份证号', |
| 281 | - required: (value) => !!value || '此项为必填项' | 318 | + required: value => !!value || '此项为必填项', |
| 282 | } | 319 | } |
| 283 | ``` | 320 | ``` |
| 284 | 321 | ||
| ... | @@ -289,6 +326,7 @@ export const validators = { | ... | @@ -289,6 +326,7 @@ export const validators = { |
| 289 | ## 6. 性能优化建议 [低优先级] | 326 | ## 6. 性能优化建议 [低优先级] |
| 290 | 327 | ||
| 291 | ### 6.1 不必要的重新渲染 | 328 | ### 6.1 不必要的重新渲染 |
| 329 | + | ||
| 292 | **问题**: 部分组件使用了过多的 `v-if` 而非 `v-show` | 330 | **问题**: 部分组件使用了过多的 `v-if` 而非 `v-show` |
| 293 | 331 | ||
| 294 | **修复建议**: 对于频繁切换的元素使用 `v-show` | 332 | **修复建议**: 对于频繁切换的元素使用 `v-show` |
| ... | @@ -296,6 +334,7 @@ export const validators = { | ... | @@ -296,6 +334,7 @@ export const validators = { |
| 296 | **状态**: ⬜ 未修复 | 334 | **状态**: ⬜ 未修复 |
| 297 | 335 | ||
| 298 | ### 6.2 教师端学生列表虚拟化 | 336 | ### 6.2 教师端学生列表虚拟化 |
| 337 | + | ||
| 299 | **问题**: `views/teacher/studentPage.vue` 学生列表可能很长,未使用虚拟滚动 | 338 | **问题**: `views/teacher/studentPage.vue` 学生列表可能很长,未使用虚拟滚动 |
| 300 | 339 | ||
| 301 | **修复建议**: 实现虚拟列表或分页加载 | 340 | **修复建议**: 实现虚拟列表或分页加载 |
| ... | @@ -303,6 +342,7 @@ export const validators = { | ... | @@ -303,6 +342,7 @@ export const validators = { |
| 303 | **状态**: ⬜ 未修复 | 342 | **状态**: ⬜ 未修复 |
| 304 | 343 | ||
| 305 | ### 6.3 计算属性优化 | 344 | ### 6.3 计算属性优化 |
| 345 | + | ||
| 306 | **问题**: 部分计算属性可以使用记忆化优化 | 346 | **问题**: 部分计算属性可以使用记忆化优化 |
| 307 | 347 | ||
| 308 | **状态**: ⬜ 未修复 | 348 | **状态**: ⬜ 未修复 |
| ... | @@ -312,7 +352,9 @@ export const validators = { | ... | @@ -312,7 +352,9 @@ export const validators = { |
| 312 | ## 7. 错误处理问题 [中优先级] | 352 | ## 7. 错误处理问题 [中优先级] |
| 313 | 353 | ||
| 314 | ### 7.1 缺少错误处理 | 354 | ### 7.1 缺少错误处理 |
| 355 | + | ||
| 315 | **问题文件**: | 356 | **问题文件**: |
| 357 | + | ||
| 316 | - `contexts/auth.js` (第69、81行): 缺少错误处理 | 358 | - `contexts/auth.js` (第69、81行): 缺少错误处理 |
| 317 | - 多个 API 调用处缺少 try-catch | 359 | - 多个 API 调用处缺少 try-catch |
| 318 | 360 | ||
| ... | @@ -320,6 +362,7 @@ export const validators = { | ... | @@ -320,6 +362,7 @@ export const validators = { |
| 320 | 362 | ||
| 321 | **状态**: ✅ 已修复 (2026-01-18) | 363 | **状态**: ✅ 已修复 (2026-01-18) |
| 322 | **修复详情**: 已创建 `src/composables/useErrorHandler.js`,提供以下功能: | 364 | **修复详情**: 已创建 `src/composables/useErrorHandler.js`,提供以下功能: |
| 365 | + | ||
| 323 | - `handleError` - 处理通用错误,支持自定义消息 | 366 | - `handleError` - 处理通用错误,支持自定义消息 |
| 324 | - `handleApiResponse` - 处理 API 响应,自动检查 `code === 1` | 367 | - `handleApiResponse` - 处理 API 响应,自动检查 `code === 1` |
| 325 | - `handleAsyncOperation` - 处理异步操作,集成成功/失败回调 | 368 | - `handleAsyncOperation` - 处理异步操作,集成成功/失败回调 |
| ... | @@ -328,6 +371,7 @@ export const validators = { | ... | @@ -328,6 +371,7 @@ export const validators = { |
| 328 | - `DEFAULT_ERROR_MESSAGE` - 默认错误消息 | 371 | - `DEFAULT_ERROR_MESSAGE` - 默认错误消息 |
| 329 | 372 | ||
| 330 | **已应用到组件**: | 373 | **已应用到组件**: |
| 374 | + | ||
| 331 | - `src/views/teacher/checkinPage.vue` ✅ - 使用 `handleError` 处理审核操作错误 | 375 | - `src/views/teacher/checkinPage.vue` ✅ - 使用 `handleError` 处理审核操作错误 |
| 332 | 376 | ||
| 333 | --- | 377 | --- |
| ... | @@ -335,7 +379,9 @@ export const validators = { | ... | @@ -335,7 +379,9 @@ export const validators = { |
| 335 | ## 8. 组件命名不一致 [低优先级] | 379 | ## 8. 组件命名不一致 [低优先级] |
| 336 | 380 | ||
| 337 | ### 8.1 组件命名风格不统一 | 381 | ### 8.1 组件命名风格不统一 |
| 382 | + | ||
| 338 | **问题**: | 383 | **问题**: |
| 384 | + | ||
| 339 | - 有些组件使用 PascalCase: `CheckInDialog` | 385 | - 有些组件使用 PascalCase: `CheckInDialog` |
| 340 | - 有些使用 camelCase: `checkinList` | 386 | - 有些使用 camelCase: `checkinList` |
| 341 | - 路由名称不统一 | 387 | - 路由名称不统一 |
| ... | @@ -349,11 +395,13 @@ export const validators = { | ... | @@ -349,11 +395,13 @@ export const validators = { |
| 349 | ## 9. TypeScript 迁移建议 [长期] | 395 | ## 9. TypeScript 迁移建议 [长期] |
| 350 | 396 | ||
| 351 | ### 9.1 缺少类型定义 | 397 | ### 9.1 缺少类型定义 |
| 398 | + | ||
| 352 | **问题**: 项目使用纯 JavaScript,无 TypeScript 类型约束 | 399 | **问题**: 项目使用纯 JavaScript,无 TypeScript 类型约束 |
| 353 | 400 | ||
| 354 | **修复建议**: | 401 | **修复建议**: |
| 355 | 402 | ||
| 356 | #### 阶段 1: 添加类型定义文件 | 403 | #### 阶段 1: 添加类型定义文件 |
| 404 | + | ||
| 357 | ```typescript | 405 | ```typescript |
| 358 | // src/api/types.d.ts | 406 | // src/api/types.d.ts |
| 359 | export interface ApiResponse<T = any> { | 407 | export interface ApiResponse<T = any> { |
| ... | @@ -373,6 +421,7 @@ export interface Course { | ... | @@ -373,6 +421,7 @@ export interface Course { |
| 373 | ``` | 421 | ``` |
| 374 | 422 | ||
| 375 | #### 阶段 2: 关键模块迁移 | 423 | #### 阶段 2: 关键模块迁移 |
| 424 | + | ||
| 376 | 1. API 层 - 添加参数和返回值类型 | 425 | 1. API 层 - 添加参数和返回值类型 |
| 377 | 2. 组件 props 和 emits 类型 | 426 | 2. 组件 props 和 emits 类型 |
| 378 | 3. 状态管理 Context | 427 | 3. 状态管理 Context |
| ... | @@ -384,7 +433,9 @@ export interface Course { | ... | @@ -384,7 +433,9 @@ export interface Course { |
| 384 | ## 10. 工具链配置建议 [基础设施] | 433 | ## 10. 工具链配置建议 [基础设施] |
| 385 | 434 | ||
| 386 | ### 10.1 ESLint 规则完善 | 435 | ### 10.1 ESLint 规则完善 |
| 436 | + | ||
| 387 | **建议**: 添加强制 `code === 1` 检查的规则 | 437 | **建议**: 添加强制 `code === 1` 检查的规则 |
| 438 | + | ||
| 388 | ```javascript | 439 | ```javascript |
| 389 | // .eslintrc.js | 440 | // .eslintrc.js |
| 390 | rules: { | 441 | rules: { |
| ... | @@ -396,7 +447,9 @@ rules: { | ... | @@ -396,7 +447,9 @@ rules: { |
| 396 | **状态**: ⬜ 未修复 | 447 | **状态**: ⬜ 未修复 |
| 397 | 448 | ||
| 398 | ### 10.2 Prettier 配置 | 449 | ### 10.2 Prettier 配置 |
| 450 | + | ||
| 399 | **建议**: 统一代码格式化规则 | 451 | **建议**: 统一代码格式化规则 |
| 452 | + | ||
| 400 | ```json | 453 | ```json |
| 401 | { | 454 | { |
| 402 | "semi": false, | 455 | "semi": false, |
| ... | @@ -409,6 +462,7 @@ rules: { | ... | @@ -409,6 +462,7 @@ rules: { |
| 409 | **状态**: ⬜ 未修复 | 462 | **状态**: ⬜ 未修复 |
| 410 | 463 | ||
| 411 | ### 10.3 Husky Git Hooks | 464 | ### 10.3 Husky Git Hooks |
| 465 | + | ||
| 412 | **建议**: 添加提交前检查,防止提交不规范代码 | 466 | **建议**: 添加提交前检查,防止提交不规范代码 |
| 413 | 467 | ||
| 414 | **状态**: ⬜ 未修复 | 468 | **状态**: ⬜ 未修复 |
| ... | @@ -418,16 +472,19 @@ rules: { | ... | @@ -418,16 +472,19 @@ rules: { |
| 418 | ## 优先级总结 | 472 | ## 优先级总结 |
| 419 | 473 | ||
| 420 | ### 🔴 高优先级(1-2周内修复) | 474 | ### 🔴 高优先级(1-2周内修复) |
| 475 | + | ||
| 421 | 1. ~~API 响应检查问题(安全性)~~ ✅ 已完成 | 476 | 1. ~~API 响应检查问题(安全性)~~ ✅ 已完成 |
| 422 | 2. ~~当前已修改文件的问题(CompleteInfoPage.vue, IDQueryPage.vue)~~ ✅ 已完成 | 477 | 2. ~~当前已修改文件的问题(CompleteInfoPage.vue, IDQueryPage.vue)~~ ✅ 已完成 |
| 423 | 478 | ||
| 424 | ### 🟡 中优先级(1个月内修复) | 479 | ### 🟡 中优先级(1个月内修复) |
| 480 | + | ||
| 425 | 3. 硬编码常量提取 | 481 | 3. 硬编码常量提取 |
| 426 | 4. 大型组件拆分 | 482 | 4. 大型组件拆分 |
| 427 | 5. ~~重复代码提取~~ ✅ 部分完成 (5.1, 5.2, 7.1 已完成) | 483 | 5. ~~重复代码提取~~ ✅ 部分完成 (5.1, 5.2, 7.1 已完成) |
| 428 | 6. ~~错误处理完善~~ ✅ 已完成 | 484 | 6. ~~错误处理完善~~ ✅ 已完成 |
| 429 | 485 | ||
| 430 | ### 🟢 低优先级(长期优化) | 486 | ### 🟢 低优先级(长期优化) |
| 487 | + | ||
| 431 | 7. 代码风格统一 | 488 | 7. 代码风格统一 |
| 432 | 8. 性能优化 | 489 | 8. 性能优化 |
| 433 | 9. 组件命名统一 | 490 | 9. 组件命名统一 |
| ... | @@ -461,7 +518,7 @@ rules: { | ... | @@ -461,7 +518,7 @@ rules: { |
| 461 | ### 本次修复 (2026-01-18) | 518 | ### 本次修复 (2026-01-18) |
| 462 | 519 | ||
| 463 | | 编号 | 问题 | 状态 | 修复内容 | | 520 | | 编号 | 问题 | 状态 | 修复内容 | |
| 464 | -|------|------|------|----------| | 521 | +| ---- | --------------------------------- | ---- | -------------------------------------- | |
| 465 | | 0.1 | CompleteInfoPage.vue API 响应检查 | ✅ | 2处修复 | | 522 | | 0.1 | CompleteInfoPage.vue API 响应检查 | ✅ | 2处修复 | |
| 466 | | 0.2 | IDQueryPage.vue API 响应检查 | ✅ | 1处修复 | | 523 | | 0.2 | IDQueryPage.vue API 响应检查 | ✅ | 1处修复 | |
| 467 | | 1.1 | 全局 API 响应检查 | ✅ | 46个文件,68处修复 | | 524 | | 1.1 | 全局 API 响应检查 | ✅ | 46个文件,68处修复 | |
| ... | @@ -470,6 +527,7 @@ rules: { | ... | @@ -470,6 +527,7 @@ rules: { |
| 470 | | 7.1 | 错误处理 composable | ✅ | 创建 useErrorHandler.js,应用到1个组件 | | 527 | | 7.1 | 错误处理 composable | ✅ | 创建 useErrorHandler.js,应用到1个组件 | |
| 471 | 528 | ||
| 472 | ### 新增文件 | 529 | ### 新增文件 |
| 530 | + | ||
| 473 | 1. `src/composables/useImageLoader.js` - 图片加载错误处理 | 531 | 1. `src/composables/useImageLoader.js` - 图片加载错误处理 |
| 474 | 2. `src/composables/useUserInfo.js` - 用户信息获取 | 532 | 2. `src/composables/useUserInfo.js` - 用户信息获取 |
| 475 | 3. `src/composables/useErrorHandler.js` - 错误处理 | 533 | 3. `src/composables/useErrorHandler.js` - 错误处理 |
| ... | @@ -477,6 +535,7 @@ rules: { | ... | @@ -477,6 +535,7 @@ rules: { |
| 477 | ### 应用 composables 的组件清单 | 535 | ### 应用 composables 的组件清单 |
| 478 | 536 | ||
| 479 | **useImageLoader 应用到的组件** (5个): | 537 | **useImageLoader 应用到的组件** (5个): |
| 538 | + | ||
| 480 | - `src/views/HomePage.vue` - 替换第386-389行旧的 handleImageError 函数 | 539 | - `src/views/HomePage.vue` - 替换第386-389行旧的 handleImageError 函数 |
| 481 | - `src/views/courses/CourseDetailPage.vue` - 替换第618-620行旧的 handleImageError 函数 | 540 | - `src/views/courses/CourseDetailPage.vue` - 替换第618-620行旧的 handleImageError 函数 |
| 482 | - `src/views/checkout/CheckoutPage.vue` - 替换第397-399行旧的 handleImageError 函数 | 541 | - `src/views/checkout/CheckoutPage.vue` - 替换第397-399行旧的 handleImageError 函数 |
| ... | @@ -484,11 +543,14 @@ rules: { | ... | @@ -484,11 +543,14 @@ rules: { |
| 484 | - `src/views/profile/LearningRecordsPage.vue` - 替换第158-161行旧的 handleImageError 函数 | 543 | - `src/views/profile/LearningRecordsPage.vue` - 替换第158-161行旧的 handleImageError 函数 |
| 485 | 544 | ||
| 486 | **useUserInfo 应用到的组件** (2个): | 545 | **useUserInfo 应用到的组件** (2个): |
| 546 | + | ||
| 487 | - `src/views/profile/ProfilePage.vue` - 使用 `refreshUserInfo` 替代直接 API 调用 | 547 | - `src/views/profile/ProfilePage.vue` - 使用 `refreshUserInfo` 替代直接 API 调用 |
| 488 | - `src/components/layout/BottomNav.vue` - 使用 `getUserInfoFromLocal` 从本地缓存获取用户信息 | 548 | - `src/components/layout/BottomNav.vue` - 使用 `getUserInfoFromLocal` 从本地缓存获取用户信息 |
| 489 | 549 | ||
| 490 | **useErrorHandler 应用到的组件** (1个): | 550 | **useErrorHandler 应用到的组件** (1个): |
| 551 | + | ||
| 491 | - `src/views/teacher/checkinPage.vue` - 使用 `handleError` 替代 console.error + showToast 组合 | 552 | - `src/views/teacher/checkinPage.vue` - 使用 `handleError` 替代 console.error + showToast 组合 |
| 492 | 553 | ||
| 493 | ### 修复的文件数量: 46个 | 554 | ### 修复的文件数量: 46个 |
| 555 | + | ||
| 494 | ### 修复的代码位置: 68处 | 556 | ### 修复的代码位置: 68处 | ... | ... |
| ... | @@ -173,30 +173,30 @@ Vue 官方建议在 SFC + Composition API 场景使用 `<script setup>`,因为 | ... | @@ -173,30 +173,30 @@ Vue 官方建议在 SFC + Composition API 场景使用 `<script setup>`,因为 |
| 173 | 173 | ||
| 174 | 建议你把前端逻辑按“层”来想(从上到下): | 174 | 建议你把前端逻辑按“层”来想(从上到下): |
| 175 | 175 | ||
| 176 | -1) View(页面) | 176 | +1. View(页面) |
| 177 | - 只做页面编排:拿数据、传 props、处理路由跳转 | 177 | - 只做页面编排:拿数据、传 props、处理路由跳转 |
| 178 | -2) Composable(业务逻辑) | 178 | +2. Composable(业务逻辑) |
| 179 | - 负责:请求、状态、数据适配、交互流程(可测试) | 179 | - 负责:请求、状态、数据适配、交互流程(可测试) |
| 180 | -3) Service/API(接口层) | 180 | +3. Service/API(接口层) |
| 181 | - 负责:请求与返回结构,尽量不处理 UI(不弹 toast) | 181 | - 负责:请求与返回结构,尽量不处理 UI(不弹 toast) |
| 182 | -4) Utils(纯工具) | 182 | +4. Utils(纯工具) |
| 183 | - 负责:纯函数、格式化、兼容处理 | 183 | - 负责:纯函数、格式化、兼容处理 |
| 184 | 184 | ||
| 185 | ## 6. 结合本项目:可直接落地的优化清单(按收益排序) | 185 | ## 6. 结合本项目:可直接落地的优化清单(按收益排序) |
| 186 | 186 | ||
| 187 | -1) 统一 API 返回结构:逐步替换 `fn` 为 `request` | 187 | +1. 统一 API 返回结构:逐步替换 `fn` 为 `request` |
| 188 | 188 | ||
| 189 | - 目标:减少大量 `if (res && res.code)` 的防御判断,把错误信息(msg)保留下来 | 189 | - 目标:减少大量 `if (res && res.code)` 的防御判断,把错误信息(msg)保留下来 |
| 190 | - 涉及文件:[fn.js](file:///Users/huyirui/program/itomix/git/mlaj/src/api/fn.js) | 190 | - 涉及文件:[fn.js](file:///Users/huyirui/program/itomix/git/mlaj/src/api/fn.js) |
| 191 | - 现状:新代码已开始使用 `request` 函数(返回统一结构),但旧的 `fn` 函数(失败返回 `false`)仍被大量使用。建议后续开发中优先使用 `request`,并逐步重构旧代码。 | 191 | - 现状:新代码已开始使用 `request` 函数(返回统一结构),但旧的 `fn` 函数(失败返回 `false`)仍被大量使用。建议后续开发中优先使用 `request`,并逐步重构旧代码。 |
| 192 | - 风险提示:`qs` 的包名是小写 `qs`,但当前存在 `import qs from 'Qs'` 写法,在大小写敏感环境下可能无法解析(建议统一为 `qs`)。 | 192 | - 风险提示:`qs` 的包名是小写 `qs`,但当前存在 `import qs from 'Qs'` 写法,在大小写敏感环境下可能无法解析(建议统一为 `qs`)。 |
| 193 | 193 | ||
| 194 | -2) 从 1 个大页面开始拆 composable:只拆“最独立的一块功能” | 194 | +2. 从 1 个大页面开始拆 composable:只拆“最独立的一块功能” |
| 195 | 195 | ||
| 196 | - 目标:不追求一次性完美分层,但要让页面先变薄,后续才好迭代与测试 | 196 | - 目标:不追求一次性完美分层,但要让页面先变薄,后续才好迭代与测试 |
| 197 | - 典型样例:[HomePage.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/views/HomePage.vue)、[StudyDetailPage.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/views/study/StudyDetailPage.vue) | 197 | - 典型样例:[HomePage.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/views/HomePage.vue)、[StudyDetailPage.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/views/study/StudyDetailPage.vue) |
| 198 | 198 | ||
| 199 | -3) 固化格式化规则(ESLint/Prettier 选一个),把“风格争议”交给工具。 | 199 | +3. 固化格式化规则(ESLint/Prettier 选一个),把“风格争议”交给工具。 |
| 200 | 200 | ||
| 201 | ## 7. 推荐写法示例(以“无 TS、可读性优先”为前提) | 201 | ## 7. 推荐写法示例(以“无 TS、可读性优先”为前提) |
| 202 | 202 | ||
| ... | @@ -217,12 +217,12 @@ Vue 官方建议在 SFC + Composition API 场景使用 `<script setup>`,因为 | ... | @@ -217,12 +217,12 @@ Vue 官方建议在 SFC + Composition API 场景使用 `<script setup>`,因为 |
| 217 | * @param {any} raw - 原始响应 | 217 | * @param {any} raw - 原始响应 |
| 218 | * @returns {ApiResult} | 218 | * @returns {ApiResult} |
| 219 | */ | 219 | */ |
| 220 | -export const normalize_api_result = (raw) => { | 220 | +export const normalize_api_result = raw => { |
| 221 | const data = raw?.data ?? raw ?? {} | 221 | const data = raw?.data ?? raw ?? {} |
| 222 | return { | 222 | return { |
| 223 | code: Number(data.code) || 0, | 223 | code: Number(data.code) || 0, |
| 224 | data: data.data ?? null, | 224 | data: data.data ?? null, |
| 225 | - msg: data.msg ?? '' | 225 | + msg: data.msg ?? '', |
| 226 | } | 226 | } |
| 227 | } | 227 | } |
| 228 | ``` | 228 | ``` |
| ... | @@ -238,11 +238,11 @@ import { showFailToast } from 'vant' | ... | @@ -238,11 +238,11 @@ import { showFailToast } from 'vant' |
| 238 | * @param {Function} fetch_list_api - 具体接口函数 | 238 | * @param {Function} fetch_list_api - 具体接口函数 |
| 239 | * @returns {{ loading: import('vue').Ref<boolean>, list: import('vue').Ref<any[]>, load: Function }} | 239 | * @returns {{ loading: import('vue').Ref<boolean>, list: import('vue').Ref<any[]>, load: Function }} |
| 240 | */ | 240 | */ |
| 241 | -export const use_list_loader = (fetch_list_api) => { | 241 | +export const use_list_loader = fetch_list_api => { |
| 242 | const loading = ref(false) | 242 | const loading = ref(false) |
| 243 | const list = ref([]) | 243 | const list = ref([]) |
| 244 | 244 | ||
| 245 | - const load = async (params) => { | 245 | + const load = async params => { |
| 246 | loading.value = true | 246 | loading.value = true |
| 247 | try { | 247 | try { |
| 248 | const res = await fetch_list_api(params) | 248 | const res = await fetch_list_api(params) |
| ... | @@ -260,7 +260,7 @@ export const use_list_loader = (fetch_list_api) => { | ... | @@ -260,7 +260,7 @@ export const use_list_loader = (fetch_list_api) => { |
| 260 | return { | 260 | return { |
| 261 | loading, | 261 | loading, |
| 262 | list, | 262 | list, |
| 263 | - load | 263 | + load, |
| 264 | } | 264 | } |
| 265 | } | 265 | } |
| 266 | ``` | 266 | ``` |
| ... | @@ -286,6 +286,6 @@ onMounted(() => { | ... | @@ -286,6 +286,6 @@ onMounted(() => { |
| 286 | 286 | ||
| 287 | ## 8. 建议你“下一步优先做”的 3 件事(投入产出比最高) | 287 | ## 8. 建议你“下一步优先做”的 3 件事(投入产出比最高) |
| 288 | 288 | ||
| 289 | -1) 统一 API 返回结构(去掉 `false` 返回),减少上层防御代码与隐性 bug。 | 289 | +1. 统一 API 返回结构(去掉 `false` 返回),减少上层防御代码与隐性 bug。 |
| 290 | -2) 把 1-2 个大页面拆出 composable(例如 HomePage 中的某一块功能),你会立刻感受到可读性提升。 | 290 | +2. 把 1-2 个大页面拆出 composable(例如 HomePage 中的某一块功能),你会立刻感受到可读性提升。 |
| 291 | -3) 固化格式化规则(ESLint/Prettier 选一个),把“风格争议”交给工具。 | 291 | +3. 固化格式化规则(ESLint/Prettier 选一个),把“风格争议”交给工具。 | ... | ... |
-
Please register or login to post a comment