hookehuyr

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行,记录已修复和待修复问题,包含详细修复统计
This diff is collapsed. Click to expand it.
...@@ -94,9 +94,9 @@ ...@@ -94,9 +94,9 @@
94 推荐方向(渐进): 94 推荐方向(渐进):
95 95
96 - 选择一个“单一事实来源”(推荐 Pinia store 或你现在的 context 之一),并定义清晰的数据流: 96 - 选择一个“单一事实来源”(推荐 Pinia store 或你现在的 context 之一),并定义清晰的数据流:
97 - - store/context 是运行时状态 97 + - store/context 是运行时状态
98 - - localStorage 是持久化镜像(启动时 hydrate,一处写入) 98 + - localStorage 是持久化镜像(启动时 hydrate,一处写入)
99 - - axios headers 从 store/context 派生(store 更新 -> 同步更新 headers) 99 + - axios headers 从 store/context 派生(store 更新 -> 同步更新 headers)
100 100
101 ### 3.3 页面体积偏大:建议用 composables “分层” 101 ### 3.3 页面体积偏大:建议用 composables “分层”
102 102
...@@ -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,13 +217,13 @@ Vue 官方建议在 SFC + Composition API 场景使用 `<script setup>`,因为 ...@@ -217,13 +217,13 @@ 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 ```
229 229
...@@ -238,30 +238,30 @@ import { showFailToast } from 'vant' ...@@ -238,30 +238,30 @@ 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)
249 - if (res.code === 1) { 249 + if (res.code === 1) {
250 - list.value = Array.isArray(res.data?.list) ? res.data.list : [] 250 + list.value = Array.isArray(res.data?.list) ? res.data.list : []
251 - return true 251 + return true
252 - } 252 + }
253 - showFailToast(res.msg || '加载失败') 253 + showFailToast(res.msg || '加载失败')
254 - return false 254 + return false
255 - } finally { 255 + } finally {
256 - loading.value = false 256 + loading.value = false
257 - }
258 } 257 }
258 + }
259 259
260 - return { 260 + return {
261 - loading, 261 + loading,
262 - list, 262 + list,
263 - load 263 + load,
264 - } 264 + }
265 } 265 }
266 ``` 266 ```
267 267
...@@ -279,13 +279,13 @@ useTitle('消息列表') ...@@ -279,13 +279,13 @@ useTitle('消息列表')
279 const { loading, list, load } = use_list_loader(getNewsListAPI) 279 const { loading, list, load } = use_list_loader(getNewsListAPI)
280 280
281 onMounted(() => { 281 onMounted(() => {
282 - load({ page: 1, limit: 10 }) 282 + load({ page: 1, limit: 10 })
283 }) 283 })
284 </script> 284 </script>
285 ``` 285 ```
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 选一个),把“风格争议”交给工具。
......