在做问卷调查系统的移动端时,循环渲染单选和多选等组件,同一类组件绑定是一个v-model,当选中一个单选时,其他题目的单选也会被选中,多选、文本框等循环渲染组件也类似。
解决办法可以定义一个对象,将需要的数据先进行一遍处理存入对象,最后再遍历获取需要的数据,这样就可以避免v-model带来的影响。
<!-- 仅演示单选按钮,多选和文本类型类似 -->
<div class="questionnaire" v-for="(item, index) in questionList" :key="item.questionId">
<!-- 单选类型 -->
<div class="singleType" v-if="item.typeName === '单选'">
<div class="size">
{{index + 1}}、{{item.question}} [<span class="typeName">{{item.typeName}}</span>]
</div>
<van-radio-group
v-model="checkList[item.questionId]"
direction="horizontal"
v-for="singleRadio in item.answerOptions"
:key="singleRadio.id">
<van-radio
:name="singleRadio.answer"
icon-size="18px"
class="singleRadio"
>{{singleRadio.answer}}</van-radio>
</van-radio-group>
</div>
</div>
// 定义的数组和对象
questionnaireList: [], // 问卷列表
questionList: [], // 问题列表
title: null, // 问卷标题
checkList: {}, // 所选的数据对象
questionnaireId: '', // 问卷ID
questionAndAnswers: [] // 答案数组
// 重点函数,将数据分类循环存入checkList对象当中
changeCheckList() {
for(let i=0; i < this.questionList.length; i++) {
if(this.questionList[i].typeName === '单选') {
this.$set(this.checkList, this.questionList[i].questionId, '')
}
if(this.questionList[i].typeName === '多选') {
this.$set(this.checkList, this.questionList[i].questionId, [])
}
if(this.questionList[i].typeName === '文本') {
this.$set(this.checkList, this.questionList[i].questionId, '')
}
}
}
// 在接口请求以后拿到数据就可以执行 changeCheckList 函数
async getQuestionnaireList() {
const questionnaireId = this.$route.params.id
const { data } = await getQuestionnaireById(questionnaireId)
console.log(data)
this.questionnaireList = data.data
this.questionnaireId = this.questionnaireList.questionnaireId
this.questionList = this.questionnaireList.questionList
this.changeCheckList()
this.title = data.data.questionnaireName
}
- 最后使用forEach遍历 questionList 数组获取需要的数据!