系列文章目录
微信小程序页面上下滚动、左右滑动(一)
文章目录
系列文章目录前言项目结构解决问题11.pretest页面2.test页面解决问题2总结参考前言
在上一篇文章,讲解了再微信小程序中如何实现页面上下滚动、左右滑动。但是,此处有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
解决问题1
当有多少个可以滑动的页面时,就会渲染多少个组件
1.pretest页面
pretest.jsComponent({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.indexconst quesArr = this.data.quesArrwx.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 npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsimport warningswarnings.filterwarnings('ignore')import sslssl._create_default_https_context = ssl._create_unverified_context
页面效果
2.test页面
test.jslet eventChannelComponent({behaviors: [require('miniprogram-computed')],computed: {// 待渲染的数组rQuesArr (data) {const {currentTab, quesArr} = datareturn 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} = datareturn curQuesObj ? curQuesObj.typeName : ''},currentGcolor (data) {const {curQuesObj} = datareturn curQuesObj ? curQuesObj.currentGcolor : ''},currentGscore (data) {const {curQuesObj} = datareturn curQuesObj ? curQuesObj.currentGscore : ''},currentFcolor (data) {const {curQuesObj} = datareturn curQuesObj ? curQuesObj.currentFcolor : ''},currentFscore (data) {const {curQuesObj} = datareturn curQuesObj ? curQuesObj.currentFscore : ''},},data: {quesArr: [],// 待渲染的数组下标rCurrentTab: 0,// 真实数组下标currentTab: 0,},/*组件生命周期*/lifetimes: {ready: function () {eventChannel = this.getOpenerEventChannel()eventChannel.on('acceptDataFromOpenerPage', (data) => {const {currentTab, quesArr} = datathis.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 = 0ctab = this.data.currentTab + 1} else if (cur === 0) {// 向左滑动cur = this.data.rQuesArr.length - 1ctab = 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
步骤如下:
将swiper
的bindchange
函数替换成bindanimationfinish
函数
在改变swiper
的current
值前检测source
字段来判断是否是由于用户触摸引起
if (e.detail.source === 'touch') {}
总结
此处的左右滑动虽然解决了渲染swiper-item
过多的问题,但是swiper
组件并不能良好的无缝切入下一个页面,每次滑动的效果不尽如意。
各位看官,你们有什么思路呢?欢迎留言!