微信小程序页面上下滚动、左右滑动(二)

系列文章目录

微信小程序页面上下滚动、左右滑动(一)

前言

在上一篇文章,讲解了再微信小程序中如何实现页面上下滚动、左右滑动。但是,此处有2个缺陷。

  • 当有多少个可以滑动的页面时,就会渲染多少个组件
  • 当快速的左右滑动时,swiper 会出现卡死(无限循环滑动)的现象
    那么我们可以考虑在每次渲染 swiper-item 时,最多渲染 3 个,动态生成可滑动的页面,于是就做出了如下效果的页面。
    在这里插入图片描述
    最多只有 3swiper-item,在左右滑动时,由于下标不时的轮询,而且 swiper 的自动切换并非是无缝切换的,故在滑动 swiper-item 时,会出现向右滑动产生向左的动画效果,向左滑动产生向右的动画效果。

在这里插入图片描述

项目结构

├── index
│   ├── index.js
│   ├── index.json
│   ├── index.wxml
│   └── index.wxss
├── pretest
│   ├── pretest.js
│   ├── pretest.json
│   ├── pretest.wxml
│   └── pretest.wxss
├── test
│   ├── test.js
│   ├── test.json
│   ├── test.wxml
│   └── test.wxss

解决问题1

当有多少个可以滑动的页面时,就会渲染多少个组件

1.pretest页面

  • pretest.js
Component({
  data: {
    quesArr: [
      {
        currentGcolor: '#ccc',
        currentGscore: 3,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '单选题',
        id: 0,
      },
      {
        currentGcolor: '#ccc',
        currentGscore: 0,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '多选题',
        id: 1,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题1',
        id: 2,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题2',
        id: 3,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题3',
        id: 4,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题4',
        id: 5,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题5',
        id: 6,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题6',
        id: 7,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题7',
        id: 8,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题8',
        id: 9,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题9',
        id: 10,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题10',
        id: 11,
      },
      {
        currentGcolor: '#0AC013',
        currentGscore: 5,
        currentFcolor: '#0AC013',
        currentFscore: 5,
        typeName: '判断题11',
        id: 12,
      },
    ]
  },
  methods: {
    onTest (e) {
      const currentTab = e.currentTarget.dataset.index
      const quesArr = this.data.quesArr
      wx.navigateTo({
        url: '/pages/test/test',
        success: function(res) {
          // 通过eventChannel向被打开页面传送数据
          res.eventChannel.emit('acceptDataFromOpenerPage', { currentTab,  quesArr})
        }
      })
    }
  },
})
  • pretest.json
{
  "usingComponents": {}
}
  • pretest.wxml
<view class="p_con">
  <view wx:for="{{quesArr}}" wx:key="id" class="p_item" wx:for-index="idx" bindtap="onTest" data-index="{{idx}}">
    {{idx + 1}}-{{item.typeName}}
  </view>
</view>
  • pretest.wxss
.p_con{
  padding: 30rpx 26rpx;
  box-sizing: border-box;
}
.p_item{
  padding: 20rpx;
  margin-bottom: 20rpx;
  border-bottom: 2rpx solid #e8e8e8;
}
.p_item:last-child{
  margin-bottom: 0;
}

代码如下(示例):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context
  • 页面效果
    在这里插入图片描述

2.test页面

  • test.js
let eventChannel
Component({
  behaviors: [require('miniprogram-computed')],
  computed: {
    // 待渲染的数组
    rQuesArr (data) {
      const {currentTab, quesArr} = data
      return quesArr.filter((v, i) => i <= currentTab + 1 && i >= currentTab - 1)
    },
    quesLen (data) {
      return data.quesArr.length
    },
    curQuesObj (data) {
      return data.quesArr[data.currentTab]
    },
    quesTitle (data) {
      const {curQuesObj} = data
      return curQuesObj ? curQuesObj.typeName : ''
    },
    currentGcolor (data) {
      const {curQuesObj} = data
      return curQuesObj ? curQuesObj.currentGcolor : ''
    },
    currentGscore (data) {
      const {curQuesObj} = data
      return curQuesObj ? curQuesObj.currentGscore : ''
    },
    currentFcolor (data) {
      const {curQuesObj} = data
      return curQuesObj ? curQuesObj.currentFcolor : ''
    },
    currentFscore (data) {
      const {curQuesObj} = data
      return curQuesObj ? curQuesObj.currentFscore : ''
    },
  },
  data: {
    quesArr: [],
    // 待渲染的数组下标
    rCurrentTab: 0,
    // 真实数组下标
    currentTab: 0,
  },
  /*组件生命周期*/
  lifetimes: {
    ready: function () {
      eventChannel = this.getOpenerEventChannel()
      eventChannel.on('acceptDataFromOpenerPage', (data) => {
        const {currentTab, quesArr} = data
        this.setData({
          currentTab,
          quesArr
        })
      })
    },
  },
  methods: {
    switchTab (e){
      if (e.detail.source === 'touch') {
        let cur = e.detail.current;
        let ctab = this.data.currentTab
        // 下标为0时,禁止向左滑动
        if (cur === 0 && this.data.currentTab === 0) {
          return
        }
        // 下标为最大值时,禁止向右滑动
        if (cur === this.data.rQuesArr.length - 1 && this.data.currentTab === this.data.quesLen - 1) {
          return
        }
        if (this.data.rCurrentTab === cur) {
          if (this.data.currentTab === this.data.quesLen - 1) {
            return
          }
          if (cur === this.data.rQuesArr.length - 1) {
            // 向右滑动
            cur = 0
            ctab = this.data.currentTab + 1
          } else if (cur === 0) {
            // 向左滑动
            cur = this.data.rQuesArr.length - 1
            ctab = this.data.currentTab - 1
          }
        } else if (this.data.rCurrentTab < cur) {
          ctab = ctab + 1
        } else {
          ctab = ctab - 1
        }
        this.setData({
          currentTab: ctab
        })
        this.setData({
          rCurrentTab: this.getCur(cur)
        })
      }
    },
    getCur (cur) {
      if (this.data.currentTab === this.data.quesLen - 1) {
        return this.data.rQuesArr.length - 1
      } else if (this.data.currentTab === 0) {
        return 0
      }
      return cur
    }
  },
})
  • test.json
{
  "usingComponents": {}
}
  • test.wxml
<view class="top_wrap box flexbox_y flexbox_between">
  {{quesTitle}}
</view>
<view class="center_wrap maxw ova">
  <swiper current="{{rCurrentTab}}" bindanimationfinish="switchTab" class="maxh">
    <swiper-item wx:for="{{rQuesArr}}" wx:for-index="idx" wx:key="subNum" duration="0">
      <scroll-view scroll-y class="maxh">
        <view class="center_view box">
          <view class="item">{{idx}}-1</view>
          <view class="item">2</view>
          <view class="item">3</view>
          <view class="item">4</view>
          <view class="item">5</view>
          <view class="item">6</view>
          <view class="item">1</view>
          <view class="item">2</view>
          <view class="item">3</view>
          <view class="item">4</view>
          <view class="item">5</view>
          <view class="item">6</view>
        </view>
      </scroll-view>
    </swiper-item>
  </swiper>
</view>
<view class="foot_wrap box flexbox_y flexbox_between">
  <view>得分:<text style="color: {{currentGcolor}}">{{currentGscore}}</text><text style="color: {{currentFcolor}}">/{{currentFscore}}</text></view>
  <view>{{currentTab + 1}}<text class="sch-ccc">/{{quesLen}}</text></view>
</view>
  • test.wxss
page{
  position: static;
}
.top_wrap{
  height: 106rpx;
  color: #333;
  padding: 0 36rpx;
  border-bottom: 2rpx solid #E8E8E8;
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 1;
}

.center_wrap{
  position: fixed;
  top: 108rpx;
  bottom: 120rpx;
  z-index: -1;
}

.center_wrap .item{
  height: 300rpx;
  margin: 15rpx;
}

.center_view{
  padding: 30rpx 36rpx;
}

.foot_wrap{
  height: 118rpx;
  color: #333;
  padding: 0 36rpx;
  border-top: 2rpx solid #E8E8E8;
  position: fixed;
  bottom: 0;
  width: 100%;
  z-index: 1;
}


.flexbox_y {
  display: flex;
  align-items: center;
}

.flexbox_between{
  display: flex;
  justify-content: space-between;
}

.maxh{
  height: 100%;
}

.maxw{
  width: 100%;
}

.box{
  box-sizing: border-box;
}

.sch-ccc{
  color: #ccc;
}

.ova{
  overflow: auto;
}
  • 页面效果
    在这里插入图片描述

解决问题2

步骤如下:

  • swiperbindchange 函数替换成 bindanimationfinish函数
    在这里插入图片描述

  • 在改变 swipercurrent 值前检测 source 字段来判断是否是由于用户触摸引起
    在这里插入图片描述

if (e.detail.source === 'touch') {
}

总结

此处的左右滑动虽然解决了渲染 swiper-item 过多的问题,但是 swiper 组件并不能良好的无缝切入下一个页面,每次滑动的效果不尽如意。
各位看官,你们有什么思路呢?欢迎留言!

参考

  • 0
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值