微信小程序双联动

584 阅读2分钟

小程序实现类似饿了吗外卖页面双联动效果实现,跟个步骤走,every body come

获取数据

记住无论是Vue,React,还是小程序之类,都有一个特点数据驱动,先要把数据整理明白

module.exports = [
    {
        title: "电脑办公"
        list: [
            {
                id: 1,
                url: 'https://resource.yirenheju.cn/wechat/index/err.png',
                goodsName: '猪猪侠'
            },
            {
                id: 1,
                url: 'https://resource.yirenheju.cn/wechat/index/err.png',
                goodsName: '手机端'
            },
            {
                id: 1,
                url: 'https://resource.yirenheju.cn/wechat/index/err.png',
                goodsName: '是什么'
            },
        ]
    }
]
//图片失效自己在去找,自己粘贴,分类数据一定要多,一屏占不满,没法玩耍
//10个一上

布局

左右布局推荐使用弹性盒子

<view class="wrap">
  <view class="left">
    <block wx:for="{{listData}}" wx:key="index">
      <view class="item" style="background:{{active===index?'red':''}}" bindtap="setBoxId" data-index="{{index}}">{{item.c_name}}</view>
    </block>
  </view>
  <view class="right">
    <scroll-view scroll-y="{{true}}" style="height:500px;" scroll-into-view="{{currentId}}" scroll-with-animation="{{true}}" bindscroll="getScroll">
      <view class="scroll-wrap">
        <block wx:for="{{listData}}" wx:key="index">
          <view class="title" id="box{{index}}" style="background:red;">{{item.c_name}}</view>
          <block wx:for="{{item.list}}" wx:for-item="itm" wx:for-index="idx" wx:key="idx">
            <image src="{{itm.url}}" style="width:100px;height:100px"></image>
            <view>{{itm.goodsName}}</view>
          </block>
        </block>
      </view>
    </scroll-view>
  </view>
</view>
<style>
    .wrap{
      display: flex;
    }
    .wrap .left{
      flex-basis:200rpx;/*设置固定宽度*/
      width: 200rpx;
    }
    .wrap .right{
      flex:1;
    }
</style>

逻辑

获取所有title距离顶部,距离,然后把总高度右边list,总高度push到数组最后,然后当在滑动时,当前scroll在那个区间

//index.js
//获取应用实例
const app = getApp()
const listData = require("../../utils/mock") //数据获取
Page({
  data: {
    listData,
    currentId: "box0",
    active: 0,
    nodeTops: []
  },
  onReady(){
    //创建选择器上下文
    var  query = wx.createSelectorQuery();
    var  nodeTops = [];
    query.selectAll(".title").boundingClientRect((nodes)=>{
      nodes.map((res)=>{
        nodeTops.push(Math.round(res.top));
      })
    }).select(".scroll-wrap").boundingClientRect((res)=>{
      nodeTops.push(Math.round(res.height));
      this.setData({nodeTops});
    }).exec();
  },
  setBoxId(e){
    var index = e.target.dataset.index;
    var currentId = this.data.currentId;
    currentId = "box"+index;
    this.setData({currentId});
  },
  getScroll(e){
    var scrollTop = e.detail.scrollTop;
    var nodeTops = this.data.nodeTops;
    //实现1
     var active = nodeTops.findIndex((item,index)=>{
       return scrollTop>=nodeTops[index]&&scrollTop<nodeTops[index+1];
     })
     this.setData({active:active>0?active:0})
    
    //实现2
    for(var i=0;i<nodeTops.length;i++){
      var val1 = nodeTops[i];
      var val2 = nodeTops[i+1];
      if(scrollTop>=val1&&scrollTop<val2){
          this.setData({active:i>0?i:0})
      }
    }
  }
})

仓库地址