废话不多说,先上完成的结果图,如果觉得,功能跟你的相似,或者觉得有帮助,那么就继续阅读,copy代码,如果觉得有出入,也可以看看思路。 完成的功能:
根据后端返回值,渲染问卷题目及题目对应的选项,可以是单选,可以是输入框。禁止用户用手向左向右滑动问卷调查点击上一题跳转上一题,点击下一题,跳转下一题,最后一项是提交展示完成的进度当用户尚未选择或者输入,则弹出弹框,提示用户先输入用户选择后高亮对应item用户选择后,将选择的结果保存,最后提交最终的结果数组 后端返回的问卷数据格式如下图所示: 最后点击提交向端发送的数据格式如下: 整体不难,代码注释也写的比较清楚,有需要的自取: wxml: <view class="question-con"> <view class="line"> <view class="active" style="width:{{activeWidth}}rpx;background-color: #37C2BC;"></view> </view> <view class='qs-con'> <swiper class='sheet' current='{{curId}}'> <block wx:for="{{questions}}" wx:key="id" wx:for-index="i"> <swiper-item catchtouchmove="forbid"> <view class="title">{{item.question}}</view> <view class="option-con" wx:if="{{item.type===2}}"> <block wx:for="{{item.options}}" wx:for-item="option" wx:key="id"> <view class="option {{survey_result[i].value===option.id?'select-active':''}}" bindtap="handleSelect" data-id="{{item.id}}" data-value="{{option.id}}" data-index="{{i}}"> {{option.text}} </view> </block> </view> <view wx:else> <input data-id="{{item.id}}" data-index="{{i}}" placeholder="{{item.placeholder}}" class="range" type="number" placeholder-style="color:#C7C7C7;font-size:36rpx;" bindinput="handleInput" /> </view> </swiper-item> </block> </swiper> </view> <view class='button-group'> <view class='button' hover-class='none' bindtap='handleLast' disabled='{{curId==0}}'> 上一题 </view> <view wx:if="{{curId<count-1}}" class='button' hover-class='none' form-type='submit' bindtap='handleNext'> 下一题 </view> <view wx:else class='button' hover-class='none' form-type='submit' bindtap='handleNext'> 提交 </view> </view> </view>js文件:
// import request from '../../servers/request' import { showToast } from '../../utils/util' Page({ data: { questions: [], // 有几项问卷 count: 0, // 问卷目前正在哪项 curId: 0, // 蓝色进度条宽度 activeWidth: 0, // 向后端返回的数据 survey_result: [] }, onLoad() { // 问卷后端返回数组 const questions = [ { question: '问题一:今年高考题难吗', type: 2, id: 1, options: [ { id: 1, text: '非常困难' }, { id: 2, text: '有点难' }, { id: 3, text: '正常' }, { id: 4, text: '比较简单' }, { id: 5, text: '非常非常简单' } ] }, { question: '2. 我觉得比平时容易紧张或着急', type: 2, id: 2, options: [ { id: 6, text: '非常困难2' }, { id: 7, text: '有点难2' }, { id: 8, text: '正常2' }, { id: 9, text: '比较简单2' }, { id: 10, text: '非常非常简单2' } ] }, { question: '3. 我觉得比平时容易紧张或着急', type: 2, id: 3, options: [ { id: 11, text: '非常困难3' }, { id: 12, text: '有点难3' }, { id: 13, text: '正常3' }, { id: 14, text: '比较简单3' }, { id: 15, text: '非常非常简单3' } ] }, { question: '4. 高三最差一次年级排名是', type: 1, id: 4, placeholder: '请输入最差一次年级排名' }, { question: '5. 高三最好一次年级排名是', type: 1, id: 5, placeholder: '请输入最好一次年级排名' } ] this.setData({ questions: questions, count: questions.length, // 最终的问卷调查结果 survey_result: Array(questions.length).fill(0) }) }, // 点击问卷某个选项进行下一步问卷 handleNext() { const { curId, count, survey_result } = this.data if (!survey_result[curId].value) { showToast('请先选择', 'none', true) return } const step = 670 / count this.setData({ curId: curId + 1, activeWidth: step * (curId + 1) }) }, // 上一步 handleLast() { const { curId, count } = this.data if (this.data.curId !== 0) { this.setData({ curId: curId - 1 }) } const step = 670 / count this.setData({ activeWidth: step * (curId - 1) }) }, // 用户选择了某项 handleSelect(e) { console.log('e:', e) const { id, value, index } = e.currentTarget.dataset const { survey_result } = this.data survey_result.splice(index, 1, { id, value }) this.setData({ survey_result }) console.log('survey_result:', this.data.survey_result) }, // 如果有是输入框,则输入 handleInput(e) { const { value } = e.detail const { id, index } = e.currentTarget.dataset const { survey_result } = this.data survey_result.splice(index, 1, { id, value }) this.setData({ survey_result }) console.log('survey_result:', this.data.survey_result) }, // 静止用手左右滑动 forbid() { return false } })css文件:
page { height: 100%; } .question-con { display: flex; flex-direction: column; align-items: center; padding: 0 40rpx; height: 100%; } .line { box-sizing: border-box; margin-top: 70rpx; width: 670rpx; height: 8rpx; background: rgba(245, 245, 245, 1); border-radius: 60rpx; } .active { box-sizing: border-box; background-color: #37C2BC; height: 8rpx; border-radius: 60rpx; } .qs-con { width: 100%; margin-top: 48rpx; flex: 1; } .sheet { display: flex; flex-direction: column; height: 100%; } .title { font-size: 36rpx; font-weight: 600; line-height: 50rpx; color: rgba(33, 33, 33, 1); } .option-con { margin-top: 84rpx; display: flex; flex-direction: column; align-items: center; font-size: 32rpx; font-weight: 400; color: rgba(0, 0, 0, 1); } .option { width: 400rpx; line-height: 100rpx; background: rgba(245, 245, 245, 1); border-radius: 60rpx; text-align: center; } .option-con :not(:first-child) { margin-top: 30rpx; } .range { margin-top: 16rpx; color: #37C2BC; } .button-group { display: flex; flex-direction: row; width: 80%; height: 150rpx; margin: auto; justify-content: space-between; align-items: center; } .button { background: #37C2BC; border-radius: 8rpx; font-size: 32rpx; line-height: 88rpx; height: 88rpx; width: 172rpx; font-weight: bold; text-align: center; color: #fff; } .button::after { border: 0; } .select-active { background-color: #37C2BC; color: #fff; }注释比较清楚了,多看几遍就懂了,关键字高亮的思想就是,将需要展示的文本,根据关键字进行拆成数组,然后再根据关键字判断是否需要高亮。如果有不懂的可以加我微信qdw1370336125相互交流。
