vb.net 遍历目录 按日期排序_之家小程序轻松玩转仿通讯录拼音首字母排序

ab82f914557ddc5443f62f8ee33a2263.gif

   总篇66篇 2019年 第40篇

众所周知,小程序是在腾讯云端存放,用户无需加载安装,通过扫一扫或者搜一下即可打开应用,能做出很多H5做不到的功能,开发成本和H5差不多,相对于APP开发成本要低,已经成为超级APP们角逐的焦点,汽车之家在这样的背景下推出了自己“小程序”,之家小程序采用自由组装组件的方式,为用户提供全面的「内容+数据+服务」的封装。
言归正传本文将以之家车系列表为例,聊一聊如何之家小程序如何实现常见仿通讯录A-Z排序功能,获取数据首字母,仿造联系人实现A-Z字母排序,实现字母索引定位功 能,监听字母滚动以及连续触摸滑动到指定字母位置。 一、效果演示

15d4d5409fc712f224622c3fff4b7080.gif

二、自定义组件封装提取

为了该功能在项目中重复使用方便,我们将改功能封装成自己的组件,在根目录上建立一个components的文件夹,在里面自定义一个文件如:letterSortPicker

464c436f2485488ddc2237a1ed3f9164.png

配置文件index.json

{

  "component": true// 是否使用组件

}

页面布局index.wxml

<viewclass='brand_box'>

<scroll-viewclass='brand_left'scroll-y="true"style='width:100%;height:{{cHeight}}px;'bindscroll="scrollLeft"enable-back-to-topscroll-with-animationscroll-into-view='{{toView}}'>

        <blockwx:for='{{cityList}}'wx:key='this'wx:for-item='letterItem'wx:for-index='letterIndex'>

          <viewclass='brand_letter_box'id="{{'index'+letterItem.first}}">

            <viewclass='brand_first_letter'>{{letterItem.first}}view>

            <viewclass="car-item"wx:for='{{letterItem.data}}'wx:key='this'data-types='list'catchtap='brandTap'data-index='{{index}}'data-id='{{item.id}}'>

              <viewclass="icon-box">

              ...

                <imageclass='icon'wx:if='{{item.logo}}'src='{{item.logo}}'>image>

              view>

              <viewclass='brand_name'>{{item.name}}view>

            view>

          view>

        block>

  scroll-view>

  <viewclass='brand_right'catchtouchstart="clickRight"catchtouchmove="handlerMove"catchtouchend="clearLetterShow">

    <viewwx:for='{{letterList}}'wx:key="{{index}}"class="letter_item{{activeId==index?'on':''}}"id='{{item}}'data-id="{{index}}">{{item}}view>

  view>

  <viewclass="show-letter"wx:if="{{isLetterShow}}">{{letter}}view>

view>

页面为动态渲染,后台提供api(前后端约定好接口格式),服务器返回的数据格式为:

28db5837982af4eef072acf3b5014a71.png

这样,我们遍历数据list就能动态渲染出车品牌列表,同时遍历letter也能将右侧字母列表动态渲染出来。布局后的页面为:

26c8b53d449d248855b912d138ba5b28.png

父组件引入letterSortPicker子组件

{

  "navigationBarBackgroundColor": "#bf2727",

  "navigationBarTextStyle": "white",

  "navigationBarTitleText": "选择品牌",

  "usingComponents": {

    "letterSortPicker": "/component/letterSortPicker/index"

  }

}

Pages/index文件下的index.wxml

标签为json中自定义的属性名

bind:brandTap的点击事件为letterSortPicker传递过来的点击事件名(brandTap)绑定的brandTap要和子组件一样

<viewclass="container">

  <letterSortPicker

    brand_box="brand_box"

    id='letterSortPicker'

    cityList="{{cityList}}"

    letterList="{{letterList}}"

    bind:error="_error" 

    bind:success="_success">

  letterSortPicker>

  <imageclass="page-bg"src="../../images/sbg.jpg"mode="scaleToFill">image>

view>

Pages/index文件下的index.js

import*as Api from'../../utils/server'

//获取应用实例

const app =getApp()

Page({

  data: {

    cityList: {},

    letterList: {},

  },

  onLoad: function (options) {

    this.queryBrand()

  },

  onReady: function () {

    //获得letterSortPicker组件

    this.letterSortPicker = this.selectComponent("#letterSortPicker");

  },

  queryBrand() {

    let that = this

    wx.showLoading({

      title: '智能匹配中...',

      mask: true

    })

    Api.queryBrand((res)=>{

      if(res.data.code == 0) {

        that.setData({

          cityList: res.data.data.list,

          letterList: res.data.data.letter

        })

        wx.hideLoading()

      }

    })

  },

})

三、选择及连续触摸选择滚动到指定字母位置

小程序提供了可滚动视图区域组件scroll-view,可以很轻松快速的实现定位效果。

首先只需在父层scroll-view组件设置一下几个属性:

  1. Scroll-y:设置为true,允许纵向滚动;

  2. Scroll-into-view:值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素;

  3. Scroll-with-animation:设置为true,在设置滚动条位置时使用动画过渡;

<scroll-view  class='brand_left'scroll-y="true"scroll-with-animationscroll-into-

view='{{选中的子元素id}}'>

        <blockwx:for='{{品牌车系列表}}'wx:key='this'>

          <viewclass='brand_letter_box'id="{{子元素id}}">

           ...

          view>

        block>

  scroll-view>

然后实现选中或者连续触摸(按压不松手)动态生成(接口返回)字母排序列表区域效果,这里需要结合使用小程序touchstart、touchmove、touchend,使用catch事件绑定可以阻止冒泡事件和向上冒泡。

<viewclass='brand_right'catchtouchstart="clickRight"catchtouchmove="handlerMove"

catchtouchend="clearLetterShow">

    <viewwx:for='{{letterList}}'wx:key="{{index}}"class="letter_item{{activeId==index?'on':''}}"id='{{item}}'data-id="{{index}}">{{item}}view>

  view>

触摸开始clickRight方法:

clickRight: function (e) {

      let letter = e.target.id

      let i =e.target.dataset.id

      this.setData({

        isLetterShow: true,

        activeId: i,

        letter: letter,

        toView: 'index' + letter

      })

    },

连续触摸(按压不松手)handermove方法

handlerMove(e){

      let that = this

      let { cityList } = this.data;

      let moveY = e.touches[0].clientY;

      let rY = moveY - this.offsetTop;

      if (rY >= 0) {

        let index = (rY<= this.apHeight) ? 0 : Math.ceil((rY - this.apHeight) /this.apHeight)

        if (0 <= index< cityList.length) {

          let nonwAp =cityList[index];

          if (index !=that.data.activeId) {

            nonwAp && this.setData({

              isLetterShow: true,

              letter: nonwAp.first,

              activeId: index,

              toView: 'index' +nonwAp.first

            });

          }

        }

      }

    },

松开手指clearLetterShow方法

clearLetterShow(){

      this.setData({

        isLetterShow: false,

      })

    },

四、页面滚动定位可视区域对应首字母

首先,计算同首字母品牌的子元素所占高度getItemHeight方法,.car-item为单个品牌所占高度,则同首字母品牌所占高度为字母所占高度+同字母品牌个数*单个品牌所占高度,具体代码为:

// 计算列表item高度

    getItemHeight(list) {

      var query = this.createSelectorQuery();

      query.select('.car-item').boundingClientRect()

      query.select('.brand_first_letter').boundingClientRect()

      query.exec((res) => {

        var itemHeight= res[0].height;

        varletterHeight = res[1].height;

        let itemArr =list.map(v => v.data.length * itemHeight + letterHeight)

        let arr = []

        itemArr.map((vi, ci) => {

          if (ci == 0) {

            arr.push(vi)

          } else {

            arr.push(itemArr[ci] + arr[ci - 1])

          }

        })

        this.setData({

          itemArr: arr

        })

      })

    }

  }

依次叠加前一项子元素的高度,得到所有子元素所在页面位置数组,该数组如下:

8bc7b30d247699684a659b783db3f808.png

然后在父层增加滚动方法srcollLeft方法,将当前滚动位置e.detail.scrollTop与每个子元素所在位置进行比较,得到所在位置的首字母,并设置选中

scrollLeft: function (e) {

      let that = this

      let { itemArr, activeId,activeScrollTop, cHeight, cityList } = this.data;

      itemArr.every((c, ci) => {

        if(e.detail.scrollTop < c) {

          if (ci != this.data.activeId){

            let nonwAp =cityList[ci];

            nonwAp && that.setData({

              activeId: ci

            })

            return

          }

        } //false 停止遍历

        else {

          returntrue//true 继续遍历

        }

      })

    },

五、性能优化

1.  减少setData开销:
  1. 每调用一次setData, 都是逻辑层向渲染层的一次通讯,这个通信还不是直接传给webView, 而是通过走了native层,通讯的开销很大;

  2. 渲染层收到通讯后,还需要重新渲染出来,所以,一次setData带来两次开销:通信的开销 + webview更新的开销;

  3. 如果一个数据不会影响渲染层,则不必放在setData里;

  4. 用到bindScroll事件,也是一次通讯,是webview层向js逻辑层的通讯,这次通讯的开销比较大,如果回调里有setData,那性能就会很差,一定要在回调里增加条件判断来禁止不必要的setData;

2.  控制包大小,常用措施有:
  1. 压缩代码,清理冗余代码;

  2. 图片放在cdn;

  3. 采用分包策略-分包预加载和独立分包;

3.  对异步请求的优化
  1. onload的阶段就可以向服务器发起请求,不用等ready;

  2. 请求接口数据可以用storage、globalData放到缓存里,减少请求时间等待;

  3. 请求中可以先展示骨架图,缩短视觉等待时间;

4.  尽可能的使用小程序组件
  1. 自定义组件的更新只在组件内部进行,不受页面其他不能分内容的影响;

  2. 各个组件也将具有各自独立的逻辑空间。每个组件都分别拥有自己的独立的数据、setData调用;

六、总结 回顾本文,我们通过、缓存、性能优化、以及页面间通信等几个方面介绍了仿联系人功能实现,应用scroll-view、storage、globalData等组件/库以及小程序时间touchstart、touchmove、touchend实现了这些功能。 未来我们将继续优化和简洁代码,并分享更多我们在项目开发过程中总结的经验和遇到的难题。

38242b0dda3d693042a6bb6d058b246f.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值