小程序商品分类页面滑动左右联动

26 篇文章 0 订阅
4 篇文章 0 订阅

目录

系列文章目录

前言

一、vtabs是什么?

二、使用步骤

1.json引入

2.wxml中使用

3.js中代码

总结


前言

商品分类页面,左边分类及右边商品左右联动

因为微信小程序scroll-view没有h5锚点控制联动,并且需求是根据整个页面的滚动条来控制联动,所以使用了页面滚动事件onPageScroll来获取页面的滚动距离,并使用微信小程序组件vtabs和vtabs-content,vtabs获取到每个分类下面的商品模块的高度并根据位置累加

分类


一、vtabs是什么?

vtabs和vtabs-content是微信开发工具的组件,最初是使用scroll-view滑动等来控制左右联动,现在我已改为我所需要的模式。部分原始代码已注释。要使用的页面json需先引入

代码包放到下载地方:https://download.csdn.net/download/Zan_Z/87425550

二、使用步骤

1.json引入

代码如下(示例):

"mp-vtabs":"/components/weui/vtabs/index",
"mp-vtabs-content":"/components/weui/vtabs-content/index",

2.wxml中使用

spcell-block为右侧商品布局组件,使用粘性定位position: sticky;时,父级div不可有overflow: hidden;样式,否则不生效

代码如下:

<mp-vtabs
    vtabs="{{tagLists}}" 
    activeTab="{{activeTab}}" 
    bindtabclick="onTabCLick"
    bindchange="onChange"
    bindclickScrollTop="clickScrollTop"
    class="test"
    tab-bar-line-color="{{zt_color}}"
    tab-bar-active-text-color="{{zt_color}}"
    tab-bar-inactive-text-color	="#605d68"
    topHeight="{{topHeight}}"
    topScrollHeight="{{topScrollHeight}}"
    navCustomHeight="{{navBlockHeight}}"
  >
    <view style="background-color: #fff;">

      <block wx:for="{{tagLists}}" wx:key="index">
        <mp-vtabs-content tabIndex="{{index}}">
          <view class="p-right-content vtabs-content-item">
            <view class="vtabs_title" style="top:{{navBlockHeight}}px">
              <view class="sortBtn">
                <view class="fLtitle">{{tagLists[index].title}}</view>
                <view class="cutlayout" wx:if="{{item.goodsList.length>0}}">
                  <view bindtap="goodsSaleSort" data-oneindex="{{index}}" style="color: {{saleSort=='desc' && saleIndex==index ? zt_color:''}};">销量</view>
                  <view class="cutlayout" bindtap="goodsCostoSort" data-oneindex="{{index}}">
                    价格
                    <view class="iconCosto">
                      <mp-icon icon="moneypxtop" color="{{costoSort=='asc' && costoIndex==index ? zt_color:'#cccccc'}}" size="{{9}}" style="height:8px"></mp-icon>
					            <mp-icon icon="moneypxbtom" color="{{costoSort=='desc' && costoIndex==index ? zt_color:'#cccccc'}}" size="{{9}}"></mp-icon>
                    </view>
                  </view>
                </view>
              </view>
            </view>
            <view style="height: 80px; margin-bottom: 5px;" wx:if="{{item.picurl}}">
              <image style="width: 100%; height: 100%;" src="{{item.picurl}}" mode="aspectFill"></image>
            </view>
            <spcell-block wx:if="{{item.goodsList.length>0}}" bind:openselect="openselect" skinStyle="{{skinStyle}}" theme_color="{{theme_color}}" splist="{{item.goodsList}}" shop_options="{{shop_options}}" selectlayout="{{selectlayout}}"></spcell-block>			
            <view class="No_products" wx:else>暂无商品</view>
            
            <!-- 二级分类开始 -->
            <block wx:for="{{item.secondList}}" wx:key="index2" wx:for-index="index2"  wx:for-item="item2">              
              <view class="vtabs_second" style="top:{{navBlockHeight}}px">
                <view class="sortBtn">
                  <view class="fLtitle">{{item2.title}}</view>
                  <view class="cutlayout" wx:if="{{item2.goodsList.length>0}}" >
                    <view bindtap="goodsSaleSort_second" data-oneindex="{{index}}" data-twoindex="{{index2}}" style="color: {{saleSort=='desc' && saleIndex==index2 ? zt_color:''}};">销量</view>
                    <view class="cutlayout" bindtap="goodsCostoSort_second" data-oneindex="{{index}}" data-twoindex="{{index2}}">
                      价格
                      <view class="iconCosto">
                        <mp-icon icon="moneypxtop" color="{{costoSort=='asc' && costoIndex==index2 ? zt_color:'#cccccc'}}" size="{{9}}" style="height:8px"></mp-icon>
                        <mp-icon icon="moneypxbtom" color="{{costoSort=='desc' && costoIndex==index2 ? zt_color:'#cccccc'}}" size="{{9}}"></mp-icon>
                      </view>
                    </view>
                  </view>
                </view>
              </view>
              <spcell-block wx:if="{{item2.goodsList.length>0}}" bind:openselect="openselect" skinStyle="{{skinStyle}}" theme_color="{{theme_color}}" splist="{{item2.goodsList}}" shop_options="{{shop_options}}" selectlayout="{{selectlayout}}"></spcell-block>			            
              <view class="No_products" wx:else>暂无商品</view>
            </block>
           
          </view>
        </mp-vtabs-content>
      </block>
      <view class="height45"></view>
    </view>
  </mp-vtabs>

3.js中代码

var app=getApp();
Page({

  /**
   * 页面的初始数据
   */
  data: {
    skinStyle:"", //主题
    zt_color:"",

    tagLists:[], //商品列表
    activeTab:0,
    navBlockHeight:0, //标题粘性定位的位置 
    topScrollHeight:0,
    topHeight:0, //距离顶部的初始距离
    costoSort:"desc", //价格降序
    saleSort:"", //销量排序
    saleIndex:"",
  },
  customData:{
    noScroll:false, //左侧类目点击时使用
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var that=this;
    //此处代码是我项目中所使用的颜色主题,可忽略
    app.globalData.sync.LoginConfigSync.then(function (res) {
      that.setData({
        skinStyle:app.globalData.shop_options.theme,
        zt_color: app.globalData.theme_color[app.globalData.shop_options.theme],
      
      })
    })
  },
  //左侧分类点击时控制onPageScroll不再执行
  clickScrollTop(e){
    this.customData.noScroll=e.detail.noScroll
  },
  //监听屏幕滚动 
  onPageScroll: function (ev) {
    if(this.customData.noScroll){
      this.customData.noScroll=false
      return;
    }
    this.setData({
      topScrollHeight:ev.scrollTop+2
    })
    
  },
  //左侧分类及分类商品
  GetTagList: function () {
    var that = this;
     
    //此处应该是接口请求获取数据内容。数据布局如下,有二级分类
    let tag=[
        { title:"分类一", id:0, 
          goodsList:[  
            {title:"商品一", id:0,},
            {title:"商品二", id:1,}
          ],
          secondList:[  
            { title:"二级分类名一", id:0,
              goodsList:[  
                {title:"商品一", id:0,},
                {title:"商品二", id:1,}
              ],
            },
            { title:"二级分类名二", id:1,
                goodsList:[  
                {title:"商品一", id:0,},
                {title:"商品二", id:1,}
              ],
            }
          ], //二级分类
        },
        { title:"分类二", id:0, 
          goodsList:[  
            {title:"商品一", id:0,},
            {title:"商品二", id:1,}
          ],
          secondList:[  
            { title:"二级分类名一", id:0,
              goodsList:[  
                {title:"商品一", id:0,},
                {title:"商品二", id:1,}
              ],
            },
            { title:"二级分类名二", id:1,
                goodsList:[  
                {title:"商品一", id:0,},
                {title:"商品二", id:1,}
              ],
            }
          ], //二级分类
        }
     ]
     that.setData({
        tagLists:tag,
     })
    

    function csHeight(){
      wx.createSelectorQuery().select('.p-top').boundingClientRect(function (rect) {
        if(rect==null) return;
        that.setData({
          topHeight:0  //此处使用wx.createSelectorQuery()是为了延迟获取内容高度,并赋值为固定数值2,为了改变数据监听重新获取内容高度
        })
      }).exec();
        
      //此处是为了获取分类商品区域到顶部的其他内容的高度,并页面滑动时二级分类标题使用position: sticky;粘性定位到顶部的距离
      wx.createSelectorQuery().select('.stickyTop').boundingClientRect(function (rect) {
        if(rect==null) return;
        that.setData({
          navBlockHeight:rect.height-1
        })
      }).exec();
    }
  },
  // 指定排序的比较函数
  compareAsc(property){
    return function(obj1,obj2){
      var value1 = obj1[property];
      var value2 = obj2[property];
      return value1 - value2;     // 升序
    }
  },
  compareDesc(property){
    return function(obj1,obj2){
      var value1 = obj1[property];
      var value2 = obj2[property];
      return value2 - value1;     // 降序
    }
  },
   //前端排序
  //一级分类 销量 排序
  goodsSaleSort(e){
    if(this.data.costoSort){
      this.setData({
        costoSort:"",
        costoIndex:""
      })
    }
    let index=e.currentTarget.dataset.oneindex;
    let sortlist=this.data.tagLists[index].goodsList
    if(this.data.saleSort==''){
      sortlist.sort(this.compareDesc("sales"))
      this.setData({
        saleSort:"desc",
        saleIndex:index
      })
    }else{
      sortlist.sort(this.compareDesc("gt_id"))
      this.setData({
        saleSort:"",
        saleIndex:index
      })
    }
    this.setData({
      [`tagLists[${index}].goodsList`]:sortlist
    })
  },
  //一级分类 价格 排序
  goodsCostoSort(e){
    this.setData({
      saleSort:"",
      saleIndex:""
    })
    let index=e.currentTarget.dataset.oneindex;
    let List=this.data.tagLists
    let sortlist=List[index].goodsList
    if(this.data.costoSort=='desc'){
      sortlist.sort(this.compareAsc("costo"))
      this.setData({
        costoSort:"asc",
        costoIndex:index
      })
    }else{
      sortlist.sort(this.compareDesc("costo"))
      this.setData({
        costoSort:"desc",
        costoIndex:index
      })
    }
    this.setData({
      [`tagLists[${index}].goodsList`]:sortlist
    })
  },
  //二级 销量 排序
  goodsSaleSort_second(e){
    if(this.data.costoSort){
      this.setData({
        costoSort:"",
        costoIndex:""
      })
    }
    let index=e.currentTarget.dataset.oneindex;
    let index2=e.currentTarget.dataset.twoindex;
    let sortlist=this.data.tagLists[index].secondList[index2].goodsList
    if(this.data.saleSort==''){
      sortlist.sort(this.compareDesc("sales"))
      this.setData({
        saleSort:"desc",
        saleIndex:index2
      })
    }else{
      sortlist.sort(this.compareDesc("gt_id"))
      this.setData({
        saleSort:"",
        saleIndex:index2
      })
    }
    this.setData({
      [`tagLists[${index}].secondList[${index2}].goodsList`]:sortlist
    })
  },
  //二级分类 价格 排序
  goodsCostoSort_second(e){
    this.setData({
      saleSort:"",
      saleIndex:""
    })
    let index=e.currentTarget.dataset.oneindex;
    let index2=e.currentTarget.dataset.twoindex;
    let sortlist=this.data.tagLists[index].secondList[index2].goodsList
    if(this.data.costoSort=='desc'){
      sortlist.sort(this.compareAsc("costo"))
      this.setData({
        costoSort:"asc",
        costoIndex:index2
      })
    }else{
      sortlist.sort(this.compareDesc("costo"))
      this.setData({
        costoSort:"desc",
        costoIndex:index2
      })
    }
    this.setData({
      [`tagLists[${index}].secondList[${index2}].goodsList`]:sortlist
    })
  },
  onTabCLick(e) {
    const index = e.detail.index
    this.setData({activeTab: index})
  },
  onChange(e) {
    const index = e.detail.index
    this.setData({activeTab: index})
  },
  
 
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

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

  },

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

  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    this.GetTagList();
  },

  
})

4.wxss代码

.fLtitle{
  font-weight: bold;
  font-size: 14px;
}

.weui-vtabs{
  background-color: #eeeeee;
}

.weui-vtabs-bar__wrp {
  margin-bottom: 45px;
  height: calc(100vh - 250px)!important;
  position: fixed!important;
}

.weui-vtabs-content__wrp{
  width: 78%!important;
  margin-left: 22%;
  overflow: visible!important;
}

.vtabs_title, .vtabs_second{
  position: sticky;
  z-index: 98;
  background: #fff;
  padding: 10px 0;
}

.No_products{
  text-align: center;
  padding: 10px 0;
}
.itemList .sp-list:last-child{
  margin-bottom: 0px!important;
}



总结

本文介绍了如何使用小程序组件,使用页面滑动实现左右区域联动选择。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值