微信小程序中 使用swiper 滑动切换一级、二级导航

其中遇到一个大问题使我放弃了swiper的使用,swiper有一个固定高度不太好处理,最终使用了touch事件去处理触摸移动,之后会再写一篇文章记录,处理不复杂的话还是可以用swiper的

一、示例图

效果根据手指滑动切换二级导航、二级切换完成切换一级导航

 

二、page代码

(1)wxml

<!--pages/demo/demo.wxml-->
<header></header>
<tabList tabParams="{{tabParams}}" tabList="{{tabList}}" bindchangeTab="changeTab"></tabList>
<!-- 滑动切换导航 -->
<view class="page-section page-section-spacing swiper">    
  <view style="text-align: center;padding: 20rpx;">
    当前部分滑动页面 导航切换
  </view>
  <swiper
    bindtransition="changeIndicatorDots"
    style="height: 300px;"
    indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" circular="{{circular}}" vertical="{{vertical}}"
    interval="{{interval}}" duration="{{duration}}" previous-margin="{{previousMargin}}px" next-margin="{{nextMargin}}px">
    <block wx:for="{{background}}" wx:key="*this">
      <swiper-item data-id="01">
        <!-- <view class="swiper-item ">{{item}}</view> -->
        <!--  -->
        <view  data-id="0" style="padding: 0px 0px;margin: 0px 15rpx 20rpx;background-color: #ffffff;width: 100%;">
          <scroll-view scroll-x="true"style="padding: 0px 10px;" class="ip_tab_comtainers" scroll-with-animation="{{true}}" scroll-left="{{navScrollLeft}}">
            <block wx:for="{{TypeLists}}" wx:for-item="item" wx:ky = "*this" wx:for-index = "index">
              <view class="ip_tab_item_n" style="height: 30px;line-height: 40px;"  data-type="{{item.posterId}}" data-index="{{index}}">{{item.typeDesc}}
              </view>
            </block>
          </scroll-view>
        </view>
        <view data-id="1" style="padding: 0px 0px;margin: 0px 15rpx 20rpx;background-color: #ffffff;width: 100%;">
          <scroll-view scroll-x="true"style="padding: 0px 10px;" class="ip_tab_comtainers" scroll-with-animation="{{true}}" scroll-left="{{navScrollLeft}}">
            <block wx:for="{{TypeLists}}" wx:for-item="item" wx:ky = "*this" wx:for-index = "index">
              <view class="ip_tab_item_n" style="height: 30px;line-height: 40px;"  data-type="{{item.posterId}}" data-index="{{index}}">{{item.typeDesc}}
              </view>
            </block>
          </scroll-view>
        </view>
        <view data-id="2" style="padding: 0px 0px;margin: 0px 15rpx 20rpx;background-color: #ffffff;width: 100%;">
          <scroll-view scroll-x="true"style="padding: 0px 10px;" class="ip_tab_comtainers" scroll-with-animation="{{true}}" scroll-left="{{navScrollLeft}}">
            <block wx:for="{{TypeLists}}" wx:for-item="item" wx:ky = "*this" wx:for-index = "index">
              <view class="ip_tab_item_n" style="height: 30px;line-height: 40px;"  data-type="{{item.posterId}}" data-index="{{index}}">{{item.typeDesc}}
              </view>
            </block>
          </scroll-view>
        </view>
        <view  data-id="3" style="padding: 0px 0px;margin: 0px 15rpx 20rpx;background-color: #ffffff;width: 100%;">
          <scroll-view scroll-x="true"style="padding: 0px 10px;" class="ip_tab_comtainers" scroll-with-animation="{{true}}" scroll-left="{{navScrollLeft}}">
            <block wx:for="{{TypeLists}}" wx:for-item="item" wx:ky = "*this" wx:for-index = "index">
              <view class="ip_tab_item_n" style="height: 30px;line-height: 40px;"  data-type="{{item.posterId}}" data-index="{{index}}">{{item.typeDesc}}
              </view>
            </block>
          </scroll-view>
        </view>
      </swiper-item>
    </block>
  </swiper> 
  <view  style="text-align: center;padding: 20rpx;">
    当前部分滑动页面 导航不切换
  </view>     
  <view  data-id="0" style="padding: 0px 0px;margin: 0px 15rpx 20rpx;background-color: #ffffff;width: 100%;">
    <scroll-view scroll-x="true"style="padding: 0px 0px;" class="ip_tab_comtainers" scroll-with-animation="{{true}}" scroll-left="{{navScrollLeft}}">
      <block wx:for="{{TypeLists}}" wx:for-item="item" wx:ky = "*this" wx:for-index = "index">
        <view class="ip_tab_item_n" style="height: 30px;line-height: 40px;"  data-type="{{item.posterId}}" data-index="{{index}}">{{item.typeDesc}}
        </view>
      </block>
    </scroll-view>
  </view>
</view>

(2)js

// pages/demo/demo.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    // tab选项
    tabParams:{
      chooseCurrent: 0,  //默认一级导航id
      chooseCurrentTabFirst: 1, //当前导航(一级)下标
      chooseCurrentSecond: 0, //默认二级导航id
      chooseCurrentTabSecond: 1, //当前导航(二级)下标
    },
    tabList:[
      {'title':'一级tab1',id:'1',prvId:'',nextId:'2',childList:[
        {'title':'二级tab1',id:'1',prvId:'',nextId:'2',},
        {'title':'二级tab2',id:'2',prvId:'1',nextId:'3',},
        {'title':'二级tab3',id:'3',prvId:'2',nextId:'',},
      ]},
      {'title':'一级tab2',id:'2',prvId:'1',nextId:'3',childList:[
        {'title':'二级tab1',id:'1',prvId:'',nextId:'2',},
        {'title':'二级tab2',id:'2',prvId:'1',nextId:'3',},
        {'title':'二级tab3',id:'3',prvId:'2',nextId:'4',},
        {'title':'二级tab4',id:'4',prvId:'3',nextId:'',},
      ]},
      {'title':'一级tab3',id:'3',prvId:'2',nextId:'4',childList:[
        {'title':'二级tab1',id:'1',prvId:'',nextId:'2',},
        {'title':'二级tab2',id:'2',prvId:'1',nextId:'3',},
        {'title':'二级tab3',id:'3',prvId:'2',nextId:'4',},
        {'title':'二级tab4',id:'4',prvId:'3',nextId:'',},
      ]},
      {'title':'一级tab4',id:'4',prvId:'3',nextId:'',childList:[
        {'title':'二级tab1',id:'1',prvId:'',nextId:'2',},
        {'title':'二级tab2',id:'2',prvId:'1',nextId:'3',},
        {'title':'二级tab3',id:'3',prvId:'2',nextId:'4',},
        {'title':'二级tab4',id:'4',prvId:'3',nextId:'',},
      ]},
    ],//tab导航
    // 模拟滑动页面 切换导航
    openNum:true,
    spedNum:30,//滑动距离
    background: ['demo-text-1'],
    indicatorDots: false,
    vertical: false,
    autoplay: false,
    circular: false,
    interval: 2000,
    duration: 300,
    previousMargin: 0,
    nextMargin: 0,
    TypeLists: [
      {posterId: 10561005, typeDesc: "央视网"},
      {posterId: 10561003, typeDesc: "爱奇艺"},
      {posterId: 10561008, typeDesc: "腾讯视频"},
      {posterId: 10561010, typeDesc: "PPTV"},
      {posterId: 10561002, typeDesc: "优酷"},
      {posterId: 10561007, typeDesc: "哔哩哔哩"}, 
      {posterId: 10561006, typeDesc: "芒果TV"}, 
      {posterId: 10561005, typeDesc: "央视网"},
      {posterId: 10561003, typeDesc: "爱奇艺"},
      {posterId: 10561008, typeDesc: "腾讯视频"},
      {posterId: 10561010, typeDesc: "PPTV"},
      {posterId: 10561002, typeDesc: "优酷"},
      {posterId: 10561007, typeDesc: "哔哩哔哩"}, 
      {posterId: 10561006, typeDesc: "芒果TV"}, 
      {posterId: 10561004, typeDesc: "西瓜视频"}
    ],   //导航栏假数据
  },

  // 点击tab切换更新请求
  changeTab(e){
    console.log(e)
    let params = e.detail;//获取点击tab后获取导航(一级和二级id)
    // let type = params.type;//当前点击导航级别  1 代表一级
    // let id = params.id;//当前点击导航id
    // let index = params.index;//当前点击导航 index
    // if(type==1){
      this.setData({
        'tabParams.chooseCurrent':params.chooseCurrent,
        'tabParams.chooseCurrentTabFirst':params.chooseCurrentTabFirst,
        'tabParams.chooseCurrentTabSecond':params.chooseCurrentTabSecond,
        'tabParams.chooseCurrentSecond':params.chooseCurrentSecond,
      })
    // }else{
    //   this.setData({
    //     'tabParams.chooseCurrentTabSecond':id,
    //     'tabParams.chooseCurrentSecond':index
    //   })
    // }
  },
  // 滑动页面切换导航
  
  changeProperty: function (e) {
    console.log('changeProperty')
    // console.log(e)
    var propertyName = e.currentTarget.dataset.propertyName
    var newData = {}
    newData[propertyName] = e.detail.value
    this.setData(newData)
  },
  changeIndicatorDots: function (e) {
    // console.log('changeIndicatorDots')
    // console.log(e)
    // 判断左滑还是右滑
    let currentItem = this.data.tabList[this.data.tabParams.chooseCurrent];
    let currentSecondItem = this.data.tabList[this.data.tabParams.chooseCurrent].childList[this.data.tabParams.chooseCurrentSecond];
    // let openNum = true
    if(e.detail.dx == 0){
      this.setData({
        openNum:true,
      })
    }
    // 左滑
    if(e.detail.dx > 0 && e.detail.dx > this.data.spedNum && this.data.openNum ){
      // openNum = false
    console.log(e.detail.dx)
    console.log(this.data.tabParams.chooseCurrent)
      this.setData({
        openNum:false,
      })
      // 左滑
      // 先判断二级是否是最后一个
      if(this.data.tabParams.chooseCurrentSecond < this.data.tabList[this.data.tabParams.chooseCurrent].childList.length-1){
        this.setData({
          'tabParams.chooseCurrentSecond':this.data.tabParams.chooseCurrentSecond+1,
        })
        this.setData({
          'tabParams.chooseCurrentTabSecond': this.data.tabList[this.data.tabParams.chooseCurrent].childList[this.data.tabParams.chooseCurrentSecond].id,
        })
      }else{
        // 如果二级是最后一个 判断 一级是否是最后一个
        if(this.data.tabParams.chooseCurrent < this.data.tabList.length-1){
          this.setData({
            'tabParams.chooseCurrent':this.data.tabParams.chooseCurrent+1,
          })
          this.setData({
            'tabParams.chooseCurrentTabFirst':this.data.tabList[this.data.tabParams.chooseCurrent].id,
            'tabParams.chooseCurrentTabSecond':this.data.tabList[this.data.tabParams.chooseCurrent].childList[0].id,
            'tabParams.chooseCurrentSecond':0
          })
        }
      }
    }
    // 右滑
    if(e.detail.dx < 0 && e.detail.dx < this.data.spedNum*-1 && this.data.openNum ){
      // openNum = false
    console.log(e.detail.dx)
    console.log(this.data.tabParams.chooseCurrent)
      this.setData({
        openNum:false,
      })
      // 右滑
      // 先判断二级是否是第一个
      if(this.data.tabParams.chooseCurrentSecond !=0){
        this.setData({
          'tabParams.chooseCurrentSecond':this.data.tabParams.chooseCurrentSecond-1,
        })
        this.setData({
          'tabParams.chooseCurrentTabSecond': this.data.tabList[this.data.tabParams.chooseCurrent].childList[this.data.tabParams.chooseCurrentSecond].id,
        })
      }else{
        // 如果二级是第一个 判断 一级是否是第一个
        if(this.data.tabParams.chooseCurrent !=0){
          this.setData({
            'tabParams.chooseCurrent':this.data.tabParams.chooseCurrent-1,
          })
          this.setData({
            'tabParams.chooseCurrentTabFirst':this.data.tabList[this.data.tabParams.chooseCurrent].id,
            'tabParams.chooseCurrentTabSecond':this.data.tabList[this.data.tabParams.chooseCurrent].childList[0].id,
            'tabParams.chooseCurrentSecond':0
          })
        }
      }
    }
    // this.setData({
    //   indicatorDots: !this.data.indicatorDots
    // })
  },
  changeAutoplay: function (e) {
    this.setData({
      autoplay: !this.data.autoplay
    })
  },
  intervalChange: function (e) {
    this.setData({
      interval: e.detail.value
    })
  },
  durationChange: function (e) {
    this.setData({
      duration: e.detail.value
    })
  },
  // end
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

(3)wxss

/* pages/demo/demo.wxss */
/* @import "./weui.wxss"; */

page {
  background-color: #F8F8F8;
  height: 100%;
  font-size: 32rpx;
  line-height: 1.6;
}
.page-body{
  padding-top: 60rpx;
  width: 100%;
}
.page-section{
  width: 100%;
  margin-bottom: 60rpx;
}
.page-section_center{
  display: flex;
  flex-direction: column;
  align-items: center;
}
.page-section:last-child{
  margin-bottom: 0;
}
.page-section-gap{
  box-sizing: border-box;
  padding: 0 30rpx;
}
.page-section-spacing{
  box-sizing: border-box;
  padding: 200rpx 80rpx;
}
.page-section-title{
  font-size: 28rpx;
  color: #999999;
  margin-bottom: 10rpx;
  padding-left: 30rpx;
  padding-right: 30rpx;
}
.page-section-gap .page-section-title{
  padding-left: 0;
  padding-right: 0;
}

.demo-text-1{
  position: relative;
  align-items: center;
  justify-content: center;
  background-color: #1AAD19;
  color: #FFFFFF;
  font-size: 36rpx;
}
.demo-text-1:before{
  content: 'A';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.demo-text-2{
  position: relative;
  align-items: center;
  justify-content: center;
  background-color: #2782D7;
  color: #FFFFFF;
  font-size: 36rpx;
}
.demo-text-2:before{
  content: 'B';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.demo-text-3{
  position: relative;
  align-items: center;
  justify-content: center;
  background-color: #F1F1F1;
  color: #353535;
  font-size: 36rpx;
}
.demo-text-3:before{
  content: 'C';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

button{
  margin-bottom: 30rpx;
}
button:last-child{
  margin-bottom: 0;
}
.page-section-title{
  padding: 0;
}
.swiper-item{
  display: block;
  height: 150px;
}
.page-section-title{
  margin-top: 60rpx;
  position: relative;
}
.info{
  position: absolute;
  right: 0;
  color: #353535;
  font-size: 30rpx;
}
.page-foot{
  margin-top: 50rpx;
}
.ip_tab_comtainers {
  width: 100%;
  display: flex;
  /* position:fixed; */
  margin-bottom: 6rpx;
  white-space: nowrap;
  background-color: #ffffff;
}
.ip_tab_item_n {
  display: inline-block;
  margin: 0rpx 25rpx 0rpx 25rpx;
  padding: 28rpx 0rpx 20rpx 0rpx;
  color: #666666;
  font-size: 32rpx;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
}

(4)json 

{ 
  "navigationStyle": "custom",
  "usingComponents": {
    "tabList" : "../../components/tabList/tabList",
  }
}

三、tab组件代码

(1)wxml

<!--components/tabList/tabList.wxml-->
<cover-view class="tabWarp" style="top:{{navigationBarAndStatusBarHeight}};{{tabList[tabParams.chooseCurrent].childList&&tabList[tabParams.chooseCurrent].childList.length<=1?'height:96rpx':''}}">
  <!-- tab导航部分 : 一级导航 -->
  <cover-view class="tabFirst">
    <cover-view class="first" wx:for="{{tabList}}"  wx:for-item="item" wx:key = "index" wx:for-index = "index">
      <cover-view class="ip_tab_item_n" class="classItem {{tabParams.chooseCurrentTabFirst == item.id?'chooseActive':''}}" catchtap="changeTab"  data-type="1" data-id="{{item.id}}" data-index="{{index}}">
        {{item.title}}
        <cover-view class="{{tabParams.chooseCurrentTabFirst == item.id?'chooseActiveLine':'noActiveLine'}}"> </cover-view>
      </cover-view>
    </cover-view>
  </cover-view>
  <!-- tab导航部分 : 二级导航 -->
  <cover-view class="tabSecond" wx:if="{{tabList[tabParams.chooseCurrent].childList&&tabList[tabParams.chooseCurrent].childList.length>1}}">
    <cover-view wx:for="{{tabList[tabParams.chooseCurrent].childList}}" wx:for-item="item" wx:key = "index" wx:for-index = "index">
      <cover-view class="ip_tab_item_n" class="classItem {{tabParams.chooseCurrentTabSecond == item.id?'chooseActive':''}}" catchtap="changeTab"   data-type="2" data-id="{{item.id}}" data-index="{{index}}">{{item.title}}</cover-view>
    </cover-view>
  </cover-view>
</cover-view>

(2)js

// components/tabList/tabList.js
Component({
  options: {
      multipleSlots: true // 启用插槽
  },
  /**
   * 组件的属性列表
   */
  properties: {
    tabParams:{
      type: Object,
      value:{
        // chooseCurrent: 0,  //默认一级导航id
        // chooseCurrentTabFirst: 1, //当前导航(一级)下标
        // chooseCurrentSecond: 0, //默认二级导航id
        // chooseCurrentTabSecond: 1, //当前导航(二级)下标
      }
    },
    tabList:{
      type: Array,
      value:[]
    },
  },

  /**
   * 组件的初始数据
   */
  data: {
    // chooseCurrentTabFirst:1,//默认一级导航
    // chooseCurrentTabSecond:1,//默认二级导航
    // chooseCurrent:0,//当前导航
    // chooseCurrentSecond:0,//当前导航(二级)下标
    navigationBarAndStatusBarHeight:''
  },

  /**
   * 组件的方法列表
   */
  methods: {
  // 点击导航切换
  changeTab(e){
    // console.log(e)
    let type = e.currentTarget.dataset.type;//当前点击导航级别  1 代表一级
    let id = e.currentTarget.dataset.id;//当前点击导航id
    let index = e.currentTarget.dataset.index;//当前点击导航 index
    if(type==1){
      this.setData({
        'tabParams.chooseCurrent':index,
        'tabParams.chooseCurrentTabFirst':id,
        'tabParams.chooseCurrentTabSecond':this.data.tabList[index].childList[0].id,
        'tabParams.chooseCurrentSecond':0
      })
    }else{
      this.setData({
        'tabParams.chooseCurrentTabSecond':id,
        'tabParams.chooseCurrentSecond':index
      })
    };
    // 
    this.triggerEvent('changeTab',this.data.tabParams)
  },
  },
  lifetimes:{
    attached(){
      var navigationBarAndStatusBarHeight=(wx.getStorageSync('statusBarHeight') + wx.getStorageSync('navigationBarHeight'))+'px'
      this.setData({
        navigationBarAndStatusBarHeight
      })
    }
  }
})

(3)wxss

/* components/tabList/tabList.wxss */
.tabWarp{height:200rpx;box-sizing: border-box;position: fixed;top: 0rpx;left: 0rpx;width: 100%;z-index: 888;background-color: #ffffff;}
.tabWarp .tabFirst{display: flex;font-size: 30rpx;color: #333;font-weight: 500;text-align: center;background-color: #ffffff;margin-bottom: 20rpx;}
.tabWarp .tabFirst .classItem{flex: 1;text-align: center;padding: 26rpx 0rpx;position: relative; margin-left: 68rpx;}
.tabWarp .tabFirst .first:first-child .classItem{margin-left: 34rpx !important}
.tabWarp .tabFirst .chooseActive{color: #556FFD;}
.chooseActiveLine{position: absolute;left: 20%;bottom: 0rpx;width: 60%;border-bottom: 4rpx solid #556FFD;}
.tabWarp .tabSecond{display: flex;font-size: 28rpx;color: #333;font-weight: 400;text-align: center;background-color: #ffffff;margin-bottom: 20rpx;}
.tabWarp .tabSecond .classItem{display: inline-block;padding: 12rpx 24rpx;border-radius: 8rpx;background-color: #EAEDFF;color: #949AB7;font-size: 28rpx;margin-left: 16rpx;}
.tabWarp .tabSecond .chooseActive{color: #fff;background-color: #556FFD;} 

(4)json

{
  "component": true,
  "usingComponents": {}
}

四、问题总结

其中遇到一个大问题使我放弃了swiper的使用,其中就是swiper有一个固定高度不太好处理,最终使用了touch事件去处理触摸移动,之后会再写一篇文章记录

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值