vue实现问卷题目
Vue 实现问卷题目
数据模型设计
使用 Vue 的响应式特性管理问卷数据,通常设计为嵌套结构:
data() {
return {
questionnaire: {
title: "用户满意度调查",
questions: [
{
id: 1,
type: "radio", // 单选/多选/文本等
title: "您对产品满意度如何?",
options: ["非常满意", "满意", "一般", "不满意"],
required: true
},
{
id: 2,
type: "textarea",
title: "请提出改进建议:",
required: false
}
]
},
answers: {} // 存储用户回答
}
}
动态组件渲染
根据题目类型渲染不同输入组件:
<template>
<div v-for="q in questionnaire.questions" :key="q.id">
<h3>{{ q.title }}<span v-if="q.required">*</span></h3>
<!-- 单选 -->
<div v-if="q.type === 'radio'">
<label v-for="opt in q.options" :key="opt">
<input
type="radio"
v-model="answers[q.id]"
:value="opt"
:required="q.required">
{{ opt }}
</label>
</div>
<!-- 文本输入 -->
<textarea
v-else-if="q.type === 'textarea'"
v-model="answers[q.id]"
:required="q.required">
</textarea>
</div>
</template>
表单验证
通过计算属性或方法实现验证:

computed: {
isValid() {
return this.questionnaire.questions.every(q => {
return !q.required || this.answers[q.id]?.trim()
})
}
}
提交处理
异步提交时处理数据:
methods: {
async submit() {
if (!this.isValid) return alert("请完成必填项");
const payload = {
questionnaireId: this.questionnaire.id,
answers: this.answers
};
try {
await api.submitSurvey(payload);
this.$router.push('/thank-you');
} catch (error) {
console.error("提交失败:", error);
}
}
}
高级功能实现
题目逻辑跳转
通过 watch 监听答案变化:

watch: {
answers: {
handler(newVal) {
if (newVal[1] === "不满意") {
this.showFollowUpQuestion = true;
}
},
deep: true
}
}
拖拽排序
使用 vue-draggable 库:
<draggable
v-model="questionnaire.questions"
@end="saveQuestionOrder">
<!-- 题目列表 -->
</draggable>
实时保存
添加防抖自动保存:
import { debounce } from 'lodash';
created() {
this.debouncedSave = debounce(this.saveDraft, 3000);
},
watch: {
answers: {
handler() {
this.debouncedSave();
},
deep: true
}
}


