技術棧:vue+axios+vuex+vantvue
懶得整理直接貼出代碼ios
<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 { width: 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 { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; }</style><style scoped lang="less"> .questionSheet { width: 100%; height: 100%; box-sizing: border-box; overflow: scroll; -webkit-overflow-scrolling: touch; background-color: white; display: flex; flex-direction: column; .hd { width: 100%; height: 100px; font-size: 30px; line-height: 100px; text-align: center; padding: 0 20px; box-sizing: border-box; & span:nth-child(2) { width: 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 { width: 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 { width: 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>