vue实现多选答题
实现多选答题功能
在Vue中实现多选答题功能可以通过以下方式完成,涵盖数据绑定、选项选择和结果提交等关键步骤。
数据绑定与渲染
定义题目和选项的数据结构,通常使用数组存储题目信息,每个题目包含选项列表。例如:
data() {
return {
questions: [
{
id: 1,
text: "问题1",
options: [
{ id: 1, text: "选项A" },
{ id: 2, text: "选项B" }
]
}
],
selectedAnswers: {}
}
}
使用v-for渲染题目和选项:
<div v-for="question in questions" :key="question.id">
<p>{{ question.text }}</p>
<div v-for="option in question.options" :key="option.id">
<input
type="checkbox"
:id="`q${question.id}-o${option.id}`"
v-model="selectedAnswers[question.id]"
:value="option.id"
>
<label :for="`q${question.id}-o${option.id}`">{{ option.text }}</label>
</div>
</div>
处理多选逻辑
Vue的v-model可以配合数组使用,自动处理多选情况。初始化时确保selectedAnswers以数组形式存储选中值:

data() {
return {
selectedAnswers: {
1: [] // 问题ID作为键,数组存储选中选项ID
}
}
}
提交与验证
添加提交按钮和验证逻辑,确保至少选择一项:
<button @click="submitAnswers">提交答案</button>
methods: {
submitAnswers() {
const unanswered = this.questions.filter(q =>
!this.selectedAnswers[q.id] || this.selectedAnswers[q.id].length === 0
);
if (unanswered.length > 0) {
alert(`请完成第 ${unanswered.map(q => q.id).join(',')} 题`);
return;
}
console.log('提交的答案:', this.selectedAnswers);
}
}
样式优化
添加CSS美化多选界面,例如使用卡片式布局:
.question {
margin-bottom: 20px;
padding: 15px;
border: 1px solid #eee;
border-radius: 5px;
}
.options {
margin-top: 10px;
}
input[type="checkbox"] {
margin-right: 8px;
}
完整组件示例
整合以上代码的完整单文件组件:

<template>
<div class="quiz-container">
<div v-for="question in questions" :key="question.id" class="question">
<p>{{ question.text }}</p>
<div class="options">
<div v-for="option in question.options" :key="option.id">
<input
type="checkbox"
:id="`q${question.id}-o${option.id}`"
v-model="selectedAnswers[question.id]"
:value="option.id"
>
<label :for="`q${question.id}-o${option.id}`">{{ option.text }}</label>
</div>
</div>
</div>
<button @click="submitAnswers">提交答案</button>
</div>
</template>
<script>
export default {
data() {
return {
questions: [
{
id: 1,
text: "哪些是前端框架?",
options: [
{ id: 1, text: "Vue" },
{ id: 2, text: "React" },
{ id: 3, text: "Angular" },
{ id: 4, text: "Django" }
]
}
],
selectedAnswers: {
1: []
}
}
},
methods: {
submitAnswers() {
const unanswered = this.questions.filter(q =>
!this.selectedAnswers[q.id] || this.selectedAnswers[q.id].length === 0
);
if (unanswered.length > 0) {
alert(`请完成第 ${unanswered.map(q => q.id).join(',')} 题`);
return;
}
console.log('提交的答案:', this.selectedAnswers);
}
}
}
</script>
<style>
.quiz-container {
max-width: 600px;
margin: 0 auto;
}
.question {
margin-bottom: 20px;
padding: 15px;
border: 1px solid #eee;
border-radius: 5px;
}
.options {
margin-top: 10px;
}
input[type="checkbox"] {
margin-right: 8px;
}
button {
padding: 10px 20px;
background: #42b983;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
动态加载题目
从API获取题目数据:
async created() {
try {
const response = await fetch('https://api.example.com/questions');
this.questions = await response.json();
// 初始化selectedAnswers
this.selectedAnswers = this.questions.reduce((acc, q) => {
acc[q.id] = [];
return acc;
}, {});
} catch (error) {
console.error('加载题目失败:', error);
}
}
响应式更新
使用计算属性实时验证完成状态:
computed: {
isCompleted() {
return this.questions.every(q =>
this.selectedAnswers[q.id] && this.selectedAnswers[q.id].length > 0
);
}
}
绑定到按钮的禁用状态:
<button @click="submitAnswers" :disabled="!isCompleted">提交答案</button>






