如何用原生微信小程序的swiper和swiper-item寫一個問卷調查,或者是輪播圖

廢話不多說,先上完成的結果圖,如果覺得,功能跟你的相似,或者覺得有幫助,那麼就繼續閱讀,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相互交流。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章