技术栈:vue+axios+vuex+vant
懒得整理直接贴出代码
<template>
<div class="questionSheet">
<div class="hd">
<span>问诊单</span>
<span @click="handleSubmit">提交发送</span>
</div>
<div class="title">
<span>{{name}}</span>
<span>( 共{{questList.length}}个问题 )</span>
</div>
<div class="cnt">
<div class="item" v-for="(item,index) in dataList" :index="index" :key="item.id" ref="item">
<div class="tl">
<span v-if="item.questionType === 0">(单选)</span>
<span v-if="item.questionType === 1">(多选)</span>
<span v-if="item.questionType === 2">(简答)</span>
<span> {{index+1}} 、{{item.content}}</span>
</div>
<div class="quest">
<!--单选-->
<div v-if="item.questionType === 0" :index="index">
<van-radio-group v-model="item.name" @change="handleChangeRadio">
<van-radio v-for="(i,index) in item.questArr" :key="index" :name="item.id+'/'+i.id">
{{i.quest}}
</van-radio>
</van-radio-group>
</div>
<!-- 多选 -->
<div v-else-if="item.questionType === 1" :index="index" ref="checkboxGroup">
<van-checkbox-group v-model="item.name" @change="handleChangeCheckbox">
<van-checkbox @click="handleGetId(item.id)" v-for="(d, index) in item.questArr" :key="index"
:name="item.id+'/'+d.id">
{{ d.quest }}
</van-checkbox>
</van-checkbox-group>
</div>
<!--简答-->
<div v-else-if="item.questionType === 2" :index="index">
<label>
<textarea v-model="item.answer.answer" placeholder="请输入问题的答案"></textarea>
</label>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
/*
* questionType 0单选 1 多选 2简答题
* interrogationId 问诊单id
* content 问题
* answerChoose 答案单选多选
* remark 备注
* items 问题数量
* answerChoosevo 冗余设计
* 答案提交 不做强校验,可以做几题提交几题
*
* 备注:
* radio-group、checkbox-group 注意绑定的值不能重复 v-model (否则会出现,选择时不好用)
* 发送数据请求时注意:之前所有的数据提交都是用的表单提交(注意设置请求头),答案传递数组时json格式不需要用qs.strfing 转
*
* 处理逻辑:
* 1:接口请求导数据(自己组合成想要的数据类型 最好是:组合成,后台需要传递的数据结构)
* 2:根据组合好的数据类型,v-model 绑定到对应的标签上
* 3:点击radio 或者 CheckBox 根据id 查找到需要改变的数据,修改数据
* 4:点击提交发送 取出组合的数据push进一个数组
* 5:调用接口发送数据请求
* */
import {RadioGroup, Radio, Checkbox, CheckboxGroup, Toast} from 'vant';
import {mapState} from "vuex";
import {listenScrollTop} from '../util/common'
export default {
components: {
[RadioGroup.name]: RadioGroup,
[Radio.name]: Radio,
[Checkbox.name]: Checkbox,
[CheckboxGroup.name]: CheckboxGroup,
[Toast.name]: Toast
},
name: "questionSheet",
computed: {
...mapState({
questList: ({questSheet}) => questSheet.questList,
name: ({questSheet}) => questSheet.name,
customerInfo: ({profile}) => profile.customerInfo,
})
},
data() {
return {
dataList: '',
secCheckBoxId: ''
}
},
created() {
listenScrollTop();
let that = this;
/*
* 先获取个人信息,然后获取提题目重组数据
* */
async function getCustomerInfo() {
//分发profile 模块下的action获取个人信息
await that.$store.dispatch('profile/getCustomerInfo');
await getQuestList(that.customerInfo.customerId);
}
getCustomerInfo();
async function getQuestList(customerId) {
let reqData = {
id: that.$route.query.interrogationId
};
await that.$store.dispatch('questSheet/getQusetList', reqData);
let questList = that.questList;
questList.map((item, index) => {
Object.assign(item, {
answer: {
questionId: item.id,
customerId: customerId,
answer: '',
}
});
if (item.answerChoose === '') {
Object.assign(item, {questArr: []})
} else {
let arr = [];
let obj = JSON.parse(item.answerChoose);
for (let i in obj) {
let o = {};
o.quest = JSON.parse(item.answerChoose)[i];
o.id = i;
arr.push(o)
}
Object.assign(item, {questArr: arr})
}
});
that.dataList = questList;
}
},
methods: {
/*改变数据的值 单选*/
handleChangeRadio(val) {
let that = this;
let secId = Number(val.split('/')[0]);
let secAnswer = val.split('/')[1];
that.dataList.map((item, index) => {
if (secId === item.id) {
item.answer.answer = secAnswer;
}
});
},
handleGetId(id) {
this.secCheckBoxId = id;
},
/*改变数据的值 多选*/
handleChangeCheckbox(val) {
let that = this;
let str = '';//题目的答案
let secId = '';//题目的id
if (val.length) {
val.map((item, index) => {
secId = Number(item.split('/')[0]);
str += item.split('/')[1];
});
that.dataList.map((d, index) => {
if (secId === d.id) {
d.answer.answer = str;
}
});
} else {
that.dataList.map((d, index) => {
if (that.secCheckBoxId === d.id) {
d.answer.answer = '';
}
});
}
},
/*提交答案*/
handleSubmit() {
let answer = [];
this.dataList.map((item) => {
if (item.answer.answer !== '') {
answer.push(item.answer)
}
});
if (answer.length) {
this.$store.dispatch('questSheet/answerQuest', answer);
} else {
Toast({
message: '您未答题,还不能提交答案',
duration: 1200
})
}
},
}
}
</script>
<style>
.questionSheet .van-radio__label, .questionSheet .van-checkbox__label {
line-height: 80px;
font-size: 30px;
margin-left: 16px;
}
.questionSheet .van-radio__icon, .questionSheet .van-checkbox__icon {
36px;
height: 36px;
}
.questionSheet .van-radio__icon--checked .van-icon,
.questionSheet .van-checkbox__icon--checked .van-icon {
background-color: rgb(28, 164, 131);
border-color: rgb(28, 164, 131);
}
.questionSheet .van-radio__icon,
.questionSheet .van-checkbox__icon {
line-height: 36px;
}
.questionSheet .van-radio__icon .van-icon,
.questionSheet .van-checkbox__icon .van-icon {
36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
}
</style>
<style scoped lang="less">
.questionSheet {
100%;
height: 100%;
box-sizing: border-box;
overflow: scroll;
-webkit-overflow-scrolling: touch;
background-color: white;
display: flex;
flex-direction: column;
.hd {
100%;
height: 100px;
font-size: 30px;
line-height: 100px;
text-align: center;
padding: 0 20px;
box-sizing: border-box;
& span:nth-child(2) {
160px;
height: 56px;
display: flex;
align-items: center;
justify-content: center;
background-color: rgb(28, 164, 131);
border-radius: 28px;
font-size: 28px;
color: rgb(255, 255, 255);
position: absolute;
right: 20px;
top: 22px;
}
}
.title {
height: 100px;
background-color: rgb(246, 246, 246);
display: flex;
align-items: center;
padding-left: 30px;
& span:nth-child(1) {
font-size: 32px;
color: rgb(68, 68, 68);
}
& span:nth-child(2) {
font-size: 28px;
color: rgb(153, 153, 153);
margin-left: 20px;
}
}
.cnt {
flex: 1;
background-color: white;
overflow: scroll;
padding: 0 20px 20px 20px;
.item {
100%;
padding: 20px 0;
margin-top: 20px;
border-bottom: 1px solid rgb(238, 238, 238);
.tl {
display: flex;
color: rgb(153, 153, 153);
font-size: 28px;
& span:nth-child(2) {
flex: 1;
margin-left: 20px;
font-size: 30px;
color: rgb(68, 68, 68);
}
}
.quest {
font-size: 30px;
margin-top: 20px;
padding: 0 80px;
& textarea {
100%;
height: 200px;
outline: none;
background-color: rgb(246, 246, 246);
padding: 20px;
box-sizing: border-box;
border: none;
resize: none;
}
}
}
.item:first-child {
margin-top: 0;
}
}
}
</style>