微信小程序(七):仿找事吧APP附近三公里Demo

来源:互联网 发布:php extract函数漏洞 编辑:程序博客网 时间:2024/06/02 15:03

功能点:轮播;列表,下拉刷新上拉加载更多;地图;网络请求;数据绑定等
文本仿照了 找事吧app 附近三公里功能,并感谢找事吧数据的提供。考虑到数据的私密性,本文贴出的代码并没有贴出请求URL,敬请谅解。
本文基于微信小程序公测版,IDE:微信开发者工具 0.10.102800

源码下载地址 :Github

效果图如下:

enter image description here

分析一下页面,主要内容分为顶部轮播,中间10个分类图标的排版和单击事件,下部列表下拉刷新上拉加载更多。大部分知识点前面都讲过。这里主要说一下微信小程序中的数据绑定,前后台传值以及加载更多时的数据合并。

1. 数据绑定和前后台传值

中间分类图标的布局文件:

<view class="items" wx:for="{{array}}" wx:for-item="item" bindtap="typeclick"  data-code="{{item.code}}" data-text="{{item.text}}" >        <image class="item-img" mode="aspectFit" src="{{item.src}}"></image>        <view class="item-text">{{item.text}}</view></view>

可以看出是以 控制属性 wx:for 绑定数据 array 来循环渲染布局,并对view绑定了单击事件bindtap="typeclick"。因为每一个分类点击都会刷新下部列表,所以需要在事件中获得当前分类数据的code。小程序中提供自定义标签 data-XXX,供开发者使用来绑定数据,XXX 可以随意取名,这里我们用 data-code="{{item.code}}" data-text="{{item.text}}"把每条数据的code和text传给function typeclick

然后在js中的 typeclick 函数中,我们可以通过event拿到绑定的数据。

// 分类item单击事件typeclick: function (e) {    total = 0;    code = e.currentTarget.dataset.code + "";    var name = e.currentTarget.dataset.text + "";    this.data.dataArray = [];    this.setData({        title: "附近三公里: " + name    })    this.periphery();},

e.currentTarget.dataset.code 后边的code就是我们在布局文件中定义的 data-XXX 中的XXX,这里需要注意一下,因为js的机制,有时候我们拿到的数据类型可能不对,需要自己处理一下。

2. 加载更多时的数据合并

    // 网络请求    periphery: function () {        var that = this        //sliderList        wx.request({            url: 'http://xxx',            method: 'POST',            data: {                city: "深圳",                code: code,                count: count + "",                total: total + "",                lat: app.globalData.latitude + "",                lng: app.globalData.longitude + ""            },            header: {                'Accept': 'application/json'            },            success: function (res) {                that.data.dataArray = that.data.dataArray.concat(res.data.data.list)                that.setData({                    dataArray: that.data.dataArray                })                setTimeout(function () {                    that.setData({                        loadingHidden: true                    })                }, 1000)            }        })    },

因为列表有上拉刷新和下拉加载更多的功能。所以每次的网络请求通过 total和count控制每次请求的数据的页码,然后在 success 回调中把数据拼接到原来的数据集合上。

首先注意一点。在wx.request的回调中,我们不能直接用this.data.dataArray 来取data标签下的dataArray,因为这里的this代表的并不是js的全局上下文对象,他对应的是这个function的上下文。所以我们需要在 wx.request 的外部,通过一个变量来保存js的全局上下文对象,var that = this ,然后在回调中用 that.data.dataArray

然后说数据拼接,需要用到concat 关键字,他可以把其参数拼接到调用者身上。that.data.dataArray.concat(res.data.data.list) 这里需要注意请求返回的数据格式,res.data代表的是返回的json,然后自己根据数据格式拼接,直到取到数据集合。

其次因为上拉和下拉的性质不同,其处理方式也不同,下拉需要把数据集合置为空并从头开始去数据。上拉需要处理total,来取下一个count条数的数据。代码如下:

// 下拉刷新回调接口onPullDownRefresh: function () {    total = 0;    this.data.dataArray = [];    this.periphery();    wx.stopPullDownRefresh;},// 上拉加载回调接口onReachBottom: function () {    total += count;    this.periphery();},

下面附上完整的代码:

<!--main.wxml--><view>    <swiper class="swiper_box" indicator-dots="{{indicatorDots}}" vertical="{{vertical}}"            autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" bindchange="swiperchange">        <block wx:for="{{images}}">            <swiper-item bindtap="itemclick" data-id="{{item.img}}" data-name="{{item.name}}">                <image src="{{item.img}}" class="slide-image"/>            </swiper-item>        </block>    </swiper></view><!--nearby.wxml--><scroll-view class="sv" scroll-y="true">    <view style="overflow:hidden;">      <view class="items" wx:for="{{array}}" wx:for-item="item" bindtap="typeclick"  data-code="{{item.code}}" data-text="{{item.text}}" >        <image class="item-img" mode="aspectFit" src="{{item.src}}"></image>        <view class="item-text">{{item.text}}</view>      </view>    </view>    <view class="data">      <text class="data-title">{{title}}</text>      <view  style="overflow:hidden;">        <view class="data-items" wx:for="{{dataArray}}" wx:for-item="item" wx:key="id" bindtap="openmap"               data-lat="{{item.lat}}" data-lng="{{item.lng}}" data-name="{{item.name}}" data-address="{{item.address}}">          <image class="data-item-img" mode="aspectFit" src="{{item.img}}"></image>          <view class="data-item-text">            <view style="width:100%; font-size: 30rpx; padding:2rpx;">{{item.name}}</view>            <view style="width:100%; font-size: 25rpx; padding:2rpx;">{{item.address}}</view>            <view style="width:100%; font-size: 25rpx; padding:2rpx;">{{item.phone}}</view>          </view>        </view>      </view>    </view>  </scroll-view>  <loading hidden="{{loadingHidden}}">        加载中...  </loading>
/**main.wxss**/.swiper_box {    width: 100%;}swiper-item image {    width: 100%;    display: inline-block;    overflow: hidden;}.sv{  background-color:#efeff4;  margin-top: 10rpx}.items{  float:left;  width: 20%;  background-color:#fff;}.item-img{  width: 100%;   height: 60rpx;}.item-text{  width: 100%;   height: 60rpx;  font-size: 25rpx;  text-align:center;}.data{  margin-top: 10rpx;  background-color:#fff;  padding: 10rpx;}.data-title{  padding-left: 10rpx;  padding-top: 15rpx;}.data-items{  width: 100%;  margin-top: 10rpx;  margin-bottom: 10rpx;  overflow: hidden;}.data-item-img{  width: 20%;  height:120rpx;  float:left;}.data-item-text{   width: 75%;   padding: 5rpx;   height:120rpx;   float:left;}
//main.js//获取应用实例var app = getApp()var count = 10;var total = 0;var code = "2";Page({    data: {        title: "附近三公里",        indicatorDots: true,        vertical: false,        autoplay: true,        interval: 3000,        duration: 1000,        loadingHidden: false,  // loading        array: [{            code: '1',            id: 'icon_1',            src: 'http://xxx',            text: '家政'        }, {                code: '2',                id: 'icon_2',                src: 'http://xxx',                text: '药店'            }, {                code: '3',                id: 'icon_3',                src: 'http://xxx',                text: '银行'            }, {                code: '4',                id: 'icon_4',                src: 'http://xxx',                text: '维修'            }, {                code: '5',                id: 'icon_5',                src: 'http://xxx',                text: '公厕'            }, {                code: '6',                id: 'icon_6',                src: 'http://xxx',                text: '医院'            }, {                code: '7',                id: 'icon_7',                src: 'http://xxx',                text: '加油站'            }, {                code: '8',                id: 'icon_8',                src: 'http://xxx',                text: '汽车洗护'            }, {                code: '9',                id: 'icon_9',                src: 'http://xxx',                text: '营业厅'            }, {                code: '10',                id: 'icon_10',                src: 'http://xxx',                text: '停车场'            }],        dataArray: []    },    //事件处理函数    swiperchange: function (e) {        // 此处写 轮播 改变时会触发的 change 事件    },    // 轮播item点击事件    itemclick: function (e) {        wx.showToast({            title: e.currentTarget.dataset.id + "",            icon: 'success',            duration: 2000        })    },    // 分类item单击事件    typeclick: function (e) {        total = 0;        code = e.currentTarget.dataset.code + "";        var name = e.currentTarget.dataset.text + "";        this.data.dataArray = [];        this.setData({            title: "附近三公里: " + name        })        this.periphery();    },    onLoad: function () {        console.log('onLoad')        var that = this        count = 10;        total = 0;        //sliderList        wx.request({            url: 'http://xxx',            method: 'POST',            data: {                 type: "1"            },            header: {                'Accept': 'application/json'            },            success: function (res) {                that.setData({                    images: res.data.data.guanggao                })            }        })        this.periphery();    },    // 网络请求    periphery: function () {        var that = this        //sliderList        wx.request({            url: 'http://xxx',            method: 'POST',            data: {                city: "深圳",                code: code,                count: count + "",                total: total + "",                lat: app.globalData.latitude + "",                lng: app.globalData.longitude + ""            },            header: {                'Accept': 'application/json'            },            success: function (res) {                that.data.dataArray = that.data.dataArray.concat(res.data.data.list)                that.setData({                    dataArray: that.data.dataArray                })                setTimeout(function () {                    that.setData({                        loadingHidden: true                    })                }, 1000)            }        })    },    // 下拉刷新回调接口    onPullDownRefresh: function () {        total = 0;        this.data.dataArray = [];        this.periphery();        wx.stopPullDownRefresh;    },    // 上拉加载回调接口    onReachBottom: function () {        total += count;        this.periphery();    },    openmap: function (e) {        wx.openLocation({          latitude: e.currentTarget.dataset.lat , // 纬度,范围为-90~90,负数表示南纬          longitude: e.currentTarget.dataset.lng, // 经度,范围为-180~180,负数表示西经          scale: 28, // 缩放比例          name: e.currentTarget.dataset.name, // 位置名          address: e.currentTarget.dataset.address, // 地址的详细说明          success: function(res){            // success          },          fail: function() {            // fail          },          complete: function() {            // complete          }        })    },})

main.json

{    "enablePullDownRefresh": true}
1 0
原创粉丝点击