小程序模仿通讯录制作

前几天模仿通讯录做了一个组件

首先他是分为三个部分,一部分是右边的定位按钮,一部分是受控的左边内容,还有一部分就是顶部固定导航。该组件主要用了scrool-view及其一些方法。

在list.wxml里面,使用的scrool-view组件,通过该组件的scroll-into-view来实现点击右侧按钮左侧内容做到跳转锚点,scroll-with-animation="true"来实现滑动的效果,bindscroll来实现华东左侧内容右侧高亮的效果

<view >
<!-- 左侧列表内容部分 -->
  <scroll-view class="content" enable-back-to-top scroll-into-view="{{toView}}" scroll-y="true" scroll-with-animation="true" bindscroll="onPageScroll"> 
    <view wx:for="{{listMain}}" wx:for-item="group" wx:key="{{group.id}}"  id="{{ 'inToView'+group.id}}" data-id='{{group.id}}'> 
      <view class="address_top" >{{group.region}}</view> 
        <view wx:for="{{group.brands}}" wx:for-item="item" wx:key="{{item.brandId}}"> 
          <view class="address_bottom" data-id='{{item.brandId}}'>{{item.name}}</view> 
        </view> 
    </view> 
  </scroll-view> 
  <!-- 顶部固定分类 -->
  <view class="list-fixed {{fixedTitle=='' ? 'hide':''}}" style="transform:translate3d(0,{{fixedTop}}px,0);">
    <view class="fixed-title">
    {{fixedTitle}}
    </view>
  </view>
  <!-- 右侧字母导航 -->
  <view class="orientation_region"> 
    <view class="orientation">自动定位</view> 
      <block wx:for="{{listMain}}"  wx:key="{{item.id}}"> 
        <view class="orientation_city  {{isActive==item.id ? 'active':'' }}" bindtap="scrollToViewFn" data-id="{{item.id}}" >
        {{item.region}}
        </view> 
    </block> 
  </view>  
</view> 

然后在list.js里面:

首先要对数据进行处理,最好就是处理成这种格式:

[
      {
        id: "1", region: "A",
        items: [
          { id: "..", name: "阿明" },
          { id: "..", name: "奥特曼" },
          { id: "..", name: "安庆" },
          { id: "..", name: "阿曼" }
        ]
      },
      {
        id: "2", region: "B",
        items: [
          { id: "..", name: "爸爸" },
          { id: "..", name: "北京" }
        ]
      },
]
//对数据进行处理
getBrands:function(){
    var that=this;
    wx.request({
      url: '获取列表数据地址',
      success(res) {
        if(res.data.status==0){
          var someTtitle = null;
          var someArr=[];
          for(var i=0;i<res.data.data.length;i++){
            var newBrands = { brandId: res.data.data[i].brandId, name: res.data.data[i].brandName };
            if (res.data.data[i].initial != someTtitle){
              someTtitle = res.data.data[i].initial
              var newObj = {
                id: i,
                region: someTtitle,
                brands: []
              };
              someArr.push(newObj)
            }
            newObj.brands.push(newBrands);
            
          };
          //赋值给列表值,该数据就是我们后面一直用到的循环
          that.setData({
            listMain:someArr
          });
          //赋值给当前高亮的isActive
          that.setData({
            isActive: that.data.listMain[0].id,
            fixedTitle: that.data.listMain[0].region
          });

          //获取分组高度代码,见下
         
        }
      }
    })
  },

然后就是要计算每个分组的高度, 用于后面滚动判断高亮,以及固定导航分类的赋值

//计算分组高度,用于之后滚动时判断使用,wx.createSelectotQuery()获取节点信息

    var that=this;
    var number=0;
    for (let i = 0; i < that.data.listMain.length; ++i) {     
    wx.createSelectorQuery().select('#inToView'that.data.listMain[i].id).
    boundingClientRect(function (rect) {
              number = rect.height + number;
              var newArry = [{ 'height': number, 'key': rect.dataset.id, "name": that.data.listMain[i].region}]
    that.setData({
      oHeight: that.data.oHeight.concat(newArry)
    })

   }).exec();
  };

         

废话不多,直接上整体代码

Page({
  /** 
   * 页面的初始数据 
   */
  data: {
    isActive:null,   
    listMain:[],
    listTitles: [],
    fixedTitle:null,    
    toView: 'inToView0',
    oHeight:[],
    scroolHeight:0
  },
  //点击右侧字母导航定位触发
  scrollToViewFn: function (e) {
    var that=this;
    var _id = e.target.dataset.id;
    for (var i = 0; i < that.data.listMain.length; ++i) {
      if (that.data.listMain[i].id === _id) {
        that.setData({
          isActive:_id,
          toView: 'inToView' + _id
        })
        break
      }
    }
  },
  toBottom:function(e){
    console.log(e)
  },
  // 页面滑动时触发
  onPageScroll:function(e){
    this.setData({
      scroolHeight: e.detail.scrollTop
    });
    for (let i in this.data.oHeight){
      if (e.detail.scrollTop < this.data.oHeight[i].height){
        this.setData({
          isActive: this.data.oHeight[i].key,
          fixedTitle:this.data.oHeight[i].name
        });
        return false;
      }
    }
   
  },
// 处理数据格式,及获取分组高度
  getBrands:function(){
    var that=this;
    wx.request({
      url: '获取数据地址',
      success(res) {
        if(res.data.status==0){
          var someTtitle = null;
          var someArr=[];
          for(var i=0;i<res.data.data.length;i++){
            var newBrands = { brandId: res.data.data[i].brandId, name: res.data.data[i].brandName };
            if (res.data.data[i].initial != someTtitle){
              someTtitle = res.data.data[i].initial
              var newObj = {
                id: i,
                region: someTtitle,
                brands: []
              };
              someArr.push(newObj)
            }
            newObj.brands.push(newBrands);
            
          };
          //赋值给列表值
          that.setData({
            listMain:someArr
          });
          //赋值给当前高亮的isActive
          that.setData({
            isActive: that.data.listMain[0].id,
            fixedTitle: that.data.listMain[0].region
          });

          //计算分组高度,wx.createSelectotQuery()获取节点信息
          var number=0;
          for (let i = 0; i < that.data.listMain.length; ++i) {
            wx.createSelectorQuery().select('#inToView' + that.data.listMain[i].id).boundingClientRect(function (rect) {
              number = rect.height + number;
              var newArry = [{ 'height': number, 'key': rect.dataset.id, "name": that.data.listMain[i].region}]
              that.setData({
                oHeight: that.data.oHeight.concat(newArry)
              })

            }).exec();
          };
         
        }
      }
    })
  },
  onLoad: function (options) {
    var that=this;
    that.getBrands();
    
    
  }
}) 

 css代码

page{ height: 100%;} 
.content{padding-bottom: 20rpx; box-sizing: border-box; height: 100%;position: fixed} 
.location{width: 100%;} 
.location_top{height: 76rpx;line-height: 76rpx; background: #f4f4f4;color: #606660;font-size: 28rpx;padding: 0 20rpx;} 
.location_bottom{height: 140rpx;line-height: 140rpx;color: #d91f16;font-size: 28rpx;border-top: 2rpx #ebebeb solid; border-bottom: 2rpx #ebebeb solid;padding: 0 20rpx; align-items: center;display: -webkit-flex;} 
.address_top{height: 56rpx;line-height: 56rpx; background: #EBEBEB;color: #999999;font-size: 28rpx;padding: 0 20rpx;} 
.address_bottom{height: 88rpx;line-height: 88rpx; background: #fff;color: #000000;font-size: 32rpx;padding: 0 20rpx; border-bottom: 2rpx #ebebeb solid;margin-left: 20rpx;margin-right: 50rpx; } 
.location_img{width: 48rpx;height: 48rpx;position: absolute;right: 20rpx;top: 125rpx;} 
.add_city{width: 228rpx;height: 60rpx;line-height: 60rpx; text-align: center; border: 2rpx solid #ebebeb; color: #000000;margin-right: 20rpx; } 
.add_citying{width: 228rpx;height: 60rpx;line-height: 60rpx; text-align: center; border: 2rpx solid #09bb07; color: #09bb07;margin-right: 20rpx;} 
.orientation{white-space:normal;display: inline-block; width: 55rpx;height:58rpx; color: #999; text-align: center;} 
.orientation_region{ width: 55rpx;font-size: 20rpx;position: fixed;top: 100rpx; right: 0rpx;} 
.orientation_city{height: 40rpx; line-height: 40rpx;color: #000;text-align: center;} 
.active{color: #2cc1d1;}
.list-fixed{position: fixed;width: 100%;z-index: 999; height: 56rpx;line-height: 56rpx; background: #EBEBEB;color: #999999;font-size: 28rpx;padding: 0 20rpx;z-index: 9999;}

猜你喜欢

转载自blog.csdn.net/weixin_38289645/article/details/81781165