在上一篇文章,讲解了再微信小程序中如何实现页面上下滚动、左右滑动。但是,此处有2个缺陷。
当有多少个可以滑动的页面时,就会渲染多少个组件
当快速的左右滑动时,swiper
会出现卡死(无限循环滑动)的现象
那么我们可以考虑在每次渲染 swiper-item
时,最多渲染 3
个,动态生成可滑动的页面,于是就做出了如下效果的页面。
最多只有 3
个 swiper-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
当有多少个可以滑动的页面时,就会渲染多少个组件
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": {}}123
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
页面效果
test.js
let eventChannelComponent({ 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;}
页面效果
步骤如下:
将 swiper
的 bindchange
函数替换成 bindanimationfinish
函数
在改变 swiper
的 current
值前检测 source
字段来判断是否是由于用户触摸引起
if (e.detail.source === 'touch') {}12
此处的左右滑动虽然解决了渲染 swiper-item
过多的问题,但是 swiper
组件并不能良好的无缝切入下一个页面,每次滑动的效果不尽如意。
来源:https://www.freesion.com/article/23531327806/