设计一个答题卡需要考虑用户体验、功能性和界面设计等多个方面,通过合理的数据结构和简单易用的组件设计,可以提升答题效率和用户的参与感。以下是一个基础参考,可以基于此基础添加扩展各种答题效果来增强体验感~
实现效果
代码演示
代码参考
<template>
<div class="subject-container">
<header>
<p>
共计 {{ totalQuestions }} 题,已做 {{ answeredQuestions }} 题,完成度
{{ completionPercentage }}%,考试时间 1 小时 30 分钟,距离考试结束还有
01:29:28
</p>
<button @click="handleSubmit">提交</button>
</header>
<!-- 试卷题目 -->
<div class="questions-list">
<div
v-for="(item, index) in questions"
:key="index"
class="question-item"
>
<div class="question-header">
<span>{{ index + 1 }}. {{ item.question }} (单选题)</span>
<span>本题 3 分</span>
</div>
<div class="question-anwswer">
<label v-for="row in item.options" :key="row">
<input
type="radio"
:name="'question-' + index"
:value="row"
v-model="userAnswers[index]"
/>
{{ row }}
</label>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue'
interface Question {
question: string
options: string[]
answer: string
}
// 模拟题目数据 实际情况是接口返回 也可以增加各种字段满足业务需求
const questions: Question[] = [
{
question: 'Vue.js 是什么?',
options: ['框架', '库', '工具', '语言'],
answer: '框架',
},
{
question: 'JavaScript 是静态类型语言吗?',
options: ['是', '否'],
answer: '否',
},
{
question: 'TypeScript 是 JavaScript 的超集吗?',
options: ['是', '否'],
answer: '是',
},
]
const userAnswers = ref<string[]>(new Array(questions.length).fill(''))
const totalQuestions = questions.length
const answeredQuestions = computed(
() => userAnswers.value.filter((answer) => answer !== '').length
)
const completionPercentage = computed(() =>
Math.round((answeredQuestions.value / totalQuestions) * 100)
)
const handleSubmit = () => {
// 提交答题逻辑
alert('提交成功!')
}
</script>
<style scoped>
.subject-container {
width: 80%;
margin: auto;
background-color: #f8f8f8;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 10px;
border-bottom: 1px solid #ddd;
margin-bottom: 20px;
}
.questions-list {
margin-top: 20px;
}
.question-item {
margin-bottom: 20px;
background: #fff;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}
.question-header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.question-anwswer {
display: flex;
align-items: flex-start;
flex-direction: column;
}
.question-anwswer label {
display: block;
margin-bottom: 5px;
}
</style>