工作记录(三):题目模块前端,包括题库页面、答题页面、题目详情、提交分析、题解
一、整体架构
以Vue 3为核心,使用Axios处理API请求,通过拦截器机制实现统一的错误处理与请求格式化,借助OpenAPI TypeScript 代码生成器来生成 API 相关的代码。整个架构采用功能域驱动的模块划分策略,题目模块中:QuestionsView.vue作为题目列表主视图,仅负责数据展示与交互调度;
CodeEditor.vue等分页面作为核心组件,封装了代码编辑与提交详解的全部逻辑;
questionService.ts则统一管理与题目相关的API请求。
二、主要实现技术点
1. 数据状态管理
题库模块的状态管理是前端实现的核心难点之一,涉及题目数据、用户交互状态、筛选条件等多维度数据的协同更新。基于Vue 3的响应式系统,模块采用了声明式的状态管理模式,使得数据流向清晰可追踪。
把核心状态组织成多个响应式引用,包括题目列表数据dataList、总题目数total、当前页码currentPage、搜索关键词searchKeyword等。这些状态通过ref函数包装,形成响应式对象,当状态发生变化时,相关的视图会自动更新。
数据加载逻辑通过watchEffect实现自动触发,当任何影响数据加载的状态(如搜索关键词、筛选标签)发生变化时,watchEffect会自动调用loadData函数重新获取数据,框架自动处理状态与视图的同步。例如:
// 自动监听参数变化并加载数据
watchEffect(() => {
loadData();
});
其中loadData函数会根据当前的searchParams,调用后端API获取题目数据,并更新dataList和total。这样,用户每次切换筛选条件或翻页,页面都能自动刷新数据,无需手动干预。
2、题目提交分析从目录切换到详解的核心实现
首先,通过Vuex状态管理获取当前登录用户信息,将用户ID和题目ID关联起来,确保只显示相关的提交记录。在数据加载方面,使用了Vue 3的组合式API中的watchEffect来监听搜索参数的变化,这样可以自动触发数据重新加载。实现了一个智能的状态切换系统,通过isShow状态来控制列表和详情的切换显示。当用户点击查看某条提交记录的详情时,系统会保存当前的记录状态,并平滑地切换到详情视图。这个切换过程中,使用了Vue的响应式系统来确保数据的同步更新。
例如,切换详情页的逻辑可以简化为:
// 切换详情页
function showDetail(record) {
nowrecord.value = record;
isShow.value = false;
// 预加载详情数据
loadRelatedData(record.id);
}
而数据加载时,会对每条记录做预处理,比如格式化时间、解析评测信息等,提升用户体验。
3、热门标签筛选题目
通过Vue的响应式系统ref创建了一个响应式对象,用于存储所有的筛选条件。其中title用于存储题目标题的搜索关键词,tags数组用于存储选中的标签,pageSize和current用于分页控制。这个状态对象的任何变化都会触发重新加载数据的操作。
当用户点击一个标签时,如果该标签不在当前选中的标签列表中,就添加它;如果已经在列表中,就移除它。每次标签变化时都会重置页码到第一页,确保用户看到筛选后的完整结果。这里使用展开运算符来创建新的对象,而不是直接修改原对象,这样可以确保Vue能够正确追踪状态变化。
标签统计部分,系统会自动统计当前题目列表中最常见的标签,并展示前三名。代码简化如下:
// 伪代码:统计热门标签
const topTags = computed(() => {
// 统计每个标签出现次数,排序后取前三
return getTopTagsFrom(dataList.value);
});
这样,用户可以一键筛选热门标签,提升检索效率。
4、评测结果详情
系统会根据提交记录的状态,计算题目的通过率,并根据不同的评测结果展示不同的提示信息。不仅显示成功或失败,还会根据通过率给出鼓励性的提示,比如当通过率低于50%时,会提示用户"请不要灰心",用于鼓励用户,提升用户体验。
代码简化如下:
// 伪代码:计算通过率并给出提示
if (submitNum > 0) {
passrate = (acceptedNum / submitNum) * 100;
if (passrate < 50) {
showMessage("请不要灰心");
}
}
这种细致的用户关怀,有助于提升平台的友好度和用户粘性。
5、代码编辑器实现
属性监听和同步系统:
实现编辑器内容和编程语言的双向绑定。通过Vue的watch机制,确保编辑器的内容和语言设置始终与父组件保持同步。在更新内容时会先检查是否真的需要更新,避免不必要的重渲染。代码简化如下:
// 同步编辑器内容和语言
watch(props.value, (newValue) => {
if (editor.value && newValue !== editor.value.getValue()) {
editor.value.setValue(newValue);
}
});
watch(props.language, (newLang) => {
if (editor.value) {
setEditorLanguage(editor.value, newLang);
}
});
代码自动补全系统:
代码补全功能是通过 Monaco Editor 的补全提供者(CompletionItemProvider)机制实现的。当用户输入 “.” 或 “$” 等触发字符,或手动触发补全(如按下 Ctrl+Space)时,编辑器会调用补全提供者函数。这个函数首先获取当前光标位置和正在输入的内容,然后根据预定义的 Java 关键字列表(如 “public”、“private”、“class” 等)生成补全建议。每个补全建议包含显示文本(label)、类型(kind)、插入内容(insertText)和替换范围(range)等信息。当用户选择某个补全项时,编辑器会自动将当前输入的文本替换为完整的关键字。代码简化如下:
//注册补全关键字
registerCompletionProvider({
triggerCharacters: [".", "$"],
provideCompletionItems: () => {
return getJavaKeywords();
}
});
这样,用户在编写代码时可以获得智能提示,提升编程效率。
三、页面美化以及展示
1、QuestionSubmitAnalyseView.vue(提交记录分析页面)
页面由提交记录表格、分页器和详情查看按钮组成。通过自定义CSS实现按钮悬浮高亮、表格行动画等效果,提升交互体验。
// 按钮悬浮高亮
:deep(.arco-btn-text:hover) { color: 主色; background: transparent; }

2、QuestionSubmitDetailView.vue(提交详情页面)
页面包含提交时间、评测结果、代码展示等区域。通过卡片阴影、圆角、浮动分析卡片等样式,增强视觉层次感。
// 卡片阴影
.judge-result { box-shadow: 0 2px 8px rgba(0,0,0,0.05); border-radius: 8px; }

3、QuestionAnswerView.vue(题目题解页面)
采用居中布局,空状态时显示友好提示。内容区域支持Markdown渲染,便于展示丰富的题解内容。
// 空状态居中
.empty-state { display: flex; align-items: center; justify-content: center; }

4、ViewQuestionView.vue(题目查看页面)
左侧为题目描述、标签、限制条件,右侧为代码编辑区。整体采用毛玻璃和卡片风格,提升页面质感。
// 毛玻璃背景
.page-background { background-image: url(...); opacity: 0.6; }

5、QuestionsView.vue(题目列表页面)
包含左侧边栏(如日历、统计、标签筛选)、搜索栏和题目表格。表格行悬浮有动画,提升交互感。
//表格行悬浮动画
.leetcode-table :deep(.arco-table-tr:hover) { transform: translateY(-2px); }

四、总结
完成了基于 Vue 3+Element UI 的题库页面、答题页面、题目详情等核心页面和前端功能实现,通过组合式 API 管理响应式状态,实现多维度题目筛选、代码编辑器,以及提交分析页面闭环,同时运用毛玻璃效果、动态动画等手段优化视觉体验。在这个过程中学习到 Vue 3 响应式系统的深度应用,掌握了复杂状态管理与组件通信技巧,也对用户交互设计的细节打磨有了更深刻认知,为后面的开发打下基础。
2万+

被折叠的 条评论
为什么被折叠?



