上线了,自己开发的刷题小程序,vue3.0
嘿,最近我搞了个Java刷题的小程序,用Vue写的,界面和功能都还挺完整的。今天就来跟大家聊聊这个小程序是怎么实现的,代码里都藏着哪些小细节。
先看整体结构,我把整个页面分成了几个大块:顶部导航栏、题目内容区、底部按钮栏,还有一个完成后的弹窗。这种布局应该挺符合大家做题库类应用的习惯吧?
顶部导航栏
Java刷题 {{ currentIndex + 1 }}/{{ totalCount }}
这块很简单,左边是标题,右边显示当前进度,比如\"3/10\"这种。用currentIndex + 1
是因为数组索引是从0开始的,加1才符合我们平时的计数习惯。
题目内容区
首先是题干:
题目 {{ currentIndex + 1 }}: {{ currentQuestion.questionContent }}
这里用了v-if=\"currentQuestion\"
来确保数据加载完成后才显示,避免页面闪烁。
然后是选项列表,这块有点意思:
{{ String.fromCharCode(65 + idx) }} {{ option }}
我用了v-for
来循环渲染选项,parsedOptions
是处理过的选项数组。这里有个小技巧,选项字母A、B、C、D是通过String.fromCharCode(65 + idx)
生成的,65对应的就是字母A的ASCII码,这样就不用手动写每个选项的字母了。
样式方面,我用了动态class:
-
选中状态:
selected
类 -
正确答案:
correct
类(只有在显示解析时才生效) -
错误答案:
incorrect
类(选中的答案不对时才显示)
这样用户选完答案提交后,就能清楚地看到自己选的对不对,正确答案是哪个。
接下来是答案解析,只有提交答案后才会显示:
解析: {{ currentQuestion.answerExplanation }}
底部导航按钮
这里的按钮文本会根据当前状态动态变化:
-
如果是最后一题,显示\"完成练习\"
-
否则,如果已经选了答案,显示\"下一题\"
-
还没选答案的话,显示\"请选择答案\"
disabled属性也做了处理,第一题时上一题按钮禁用,最后一题没选答案时,完成按钮也会禁用,防止用户跳过题目。
完成弹窗
练习完成! 得分: {{ correctCount }}/{{ totalCount }}
全部做完后会弹出这个弹窗,显示得分,还有两个按钮:重新开始和再战错题。这个再战错题功能我觉得还挺实用的,能针对性地巩固薄弱点。
脚本部分
接下来看看逻辑实现,我用的是Vue 3的setup语法。
首先定义了一些状态变量:
const currentIndex = ref(0) // 当前题目索引const currentQuestion = ref(null) // 当前题目数据const selectedIndex = ref(-1) // 选中的选项索引,-1表示未选择const showExplanation = ref(false) // 是否显示解析const totalCount = ref(0) // 总题数const correctCount = ref(0) // 做对的题数const showResult = ref(false) // 是否显示结果弹窗
然后是一些计算属性:
// 解析选项,把字符串分割成数组const parsedOptions = computed(() => { if (!currentQuestion.value?.options) return [] return currentQuestion.value.options.split(\'\\n\') .filter(option => option.trim()) .map(option => option.replace(/^[A-Z]\\./, \'\').trim())})// 是否已选择答案const hasSelected = computed(() => selectedIndex.value !== -1)
parsedOptions
会把后端返回的选项字符串(可能是用换行分隔的)转换成数组,还会去掉每个选项前面的A.、B.这种前缀,让显示更干净。
处理选择选项的方法:
const handleSelectOption = (idx) => { if (showExplanation.value) return // 已显示解析,禁止修改 selectedIndex.value = idx}
这里加了个判断,如果已经显示解析了,就不能再改答案了,避免用户反复修改。
上一题和下一题的逻辑:
const prevQuestion = () => {if (currentIndex.value > 0) { currentIndex.value-- loadCurrentQuestion() }}const nextQuestion = () => {if (!hasSelected.value) return// 未选择答案// 检查答案是否正确if (!showExplanation.value) { const userAnswer = String.fromCharCode(65 + selectedIndex.value) if (userAnswer === currentQuestion.value.correctAnswer) { correctCount.value++ reportCorrect(currentQuestion.value.id); // 上报正确答案 } else { reportIncorrect(currentQuestion.value.id); // 上报错误答案 } showExplanation.value = true return }// 跳转到下一题if (currentIndex.value < totalCount.value - 1) { currentIndex.value++ loadCurrentQuestion() } else { // 完成所有题目 showResult.value = true }}
下一题的逻辑稍微复杂点:
-
首先检查是否已经选择答案,如果没有就直接返回
-
如果还没显示解析,就先判断答案是否正确,更新正确题数,然后显示解析
-
如果已经显示解析了,就跳到下一题,或者如果是最后一题,就显示结果弹窗
加载当前题目的方法:
const loadCurrentQuestion = () => { currentQuestion.value = questionData.value[currentIndex.value] selectedIndex.value = -1 // 重置选择状态 showExplanation.value = false // 隐藏解析}
每次切换题目时,都会重置选择状态和解析显示状态。
重新开始和再战错题的功能:
const restart = () => { currentIndex.value = 0 correctCount.value = 0 showResult.value = false uni.redirectTo({ url:\"/pages/aaa/aaa\" })}const restart2 = async () => {let resData = await expendPoint(\'java刷题\',20)if (resData.code !== 200) { uni.showModal({ title: \'提示\', content: resData.message, }); return } showResult.value = false currentIndex.value = 0 correctCount.value = 0 uni.showLoading({ title:\"加载中\", mask: true });const tms = await selectError(); // 获取错题 uni.hideLoading(); questionData.value = tms; totalCount.value = tms.length; loadCurrentQuestion()}
这里的expendPoint
是个能量消耗的接口,可能是我这个小程序里的一个积分系统,做错题练习需要消耗20点能量。
最后是页面加载时的初始化:
onMounted(async () => {let resData = await expendPoint(\'java刷题\',20)if (resData.code !== 200) { uni.showModal({ title: \'提示\', content: resData.message, }); return } uni.showLoading({ title:\"加载中\", mask: true });const tms = await randomTm(); // 获取随机题目 uni.hideLoading(); questionData.value = tms; totalCount.value = tms.length; loadCurrentQuestion()})
页面一加载就会调用接口获取题目数据,同时显示加载中提示,让用户知道正在加载。
样式部分
样式我用了scoped属性,确保不会污染其他组件。主要处理了各种状态的显示效果,比如选中、正确、错误的样式区分,还有弹窗的遮罩效果等。
总的来说,这个小程序虽然简单,但功能还挺完整的,用户体验上也做了不少细节处理。比如:
-
清晰的进度显示
-
直观的答案反馈(正确/错误)
-
详细的解析说明
-
错题重练功能
-
合理的按钮状态控制
代码结构也比较清晰,把UI和逻辑分离,方便后续维护和扩展。如果想加新功能,比如收藏题目、难度筛选什么的,也很容易在这个基础上扩展。
大家觉得这个小程序怎么样?有什么可以改进的地方欢迎一起讨论~
点击下方链接,即可体验~
速用百宝箱https://mp.weixin.qq.com/s?__biz=MzI1ODI1ODkzMA==&mid=2247497389&idx=1&sn=dd67cedd437a01b3f06507d38650ffde&chksm=ebe1b5699d11eaf0db4a06891d66a85e81642d24ac5f209576907e695aa84080485fa0af6136&scene=126&sessionid=1753317024&subscene=91&clicktime=1753317025&enterid=1753317025&key=daf9bdc5abc4e8d0431ce024e74393f3d4d7363a48a9149b474f3b8cf23986d4b35229bab8d5ea130bb8d6cac53a81552b00c36509a1417c0cd156bcc51f1eab9f4256a30fa6f38a00fce6ebe4c6687ac0a6951f6cece7c99ac7a3ad0802fec5444a13ea0b7ec6943b769291a6397feb6cb7ce96bb4dcd0ea4c3a20b94274060&ascene=0&uin=NDAwODI4MTc2&devicetype=Windows+11+x64&version=63090c37&lang=zh_CN&countrycode=CN&exportkey=n_ChQIAhIQC%2Byv%2BJhP3dcGtQjVPBMVaRLmAQIE97dBBAEAAAAAAONbCcPymDMAAAAOpnltbLcz9gKNyK89dVj0mId9lGY7cgnRR9uMjFqtA85HhyhxR%2F8MkxC519%2BAAh5oQXtwcxPqtbYuMxU9JG0jLZYRcQ6v6JjRHJNp8ys0DuFDth01%2Fp3jjmgfq9HvxRpISFTGcQeWwa5V638C1okgLeuZSo%2BIQ7HhM0cM1JDjoeoCj4RS4DVLDLeupELVNXBvlf7OkIUXSv6UqorKMIEzGKrpeQA%2BBPGRVfR3u%2BhoINPcohS22vIVXyOvaMNODUGi04FFuwOSZzsrHtd3Mkxp&acctmode=0&pass_ticket=blZdPvi3Lplm9v5ei2FR0KEPOc%2FjdsNpEJy8DRmJcCqu5pYRRJMo5GEgEjyl5FKH&wx_header=1