开发|走进小程序(二)

欢迎点击「算法与编程之美」↑关注我们!

本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。

前言

之前的博客《走进小程序》介绍了制作小程序的准备步骤和一些技术知识,这次我们从实际制作入手,边做边学。

由于小程序有许多的知识点,不能一一讲解,只能讲述一下思路然后,功能的实现,要用到什么就学习什么,这样比较会节省时间,提高效率。

我们这次要做的是一个电商类的微信小程序,下面就正式开始吧!

首页

首先要做的就是首页,一般电商的首页就是分为三大板块:轮播图、活动板块、首页列表。

大致效果如图:

大概步骤分为以下四步:

1、轮播图:根据接口数据生成banners,再用Wx:for 遍历banners生成swiper-item ,最后在swiper标签里面渲染得到的数据。

2、整点限时抢购:Date对象,topList的数据作为抢购数据, scroll-view 做横向滚动,scroll-view的宽度是屏幕宽度,里面有一个容器,这个容器可以放下所有抢购的商品,就可以横向滚动了。(扩展:比如热销排行、明星产品、猜你喜欢,样式可以优化,不限于vant组件库)

3、首页商品列表:也是先从接口取到所有列表数据,然后利用vant组件里的van-card组件循环出商品列表。

4、上拉加载:默认start值为0,每一次滚动条拉到底部的时候,start+=20,请求接下来的20条数据,onReachBottom指的就是滚动条到达底部,把数据添加到list里,就可以显示所有数据了,在这里还用到了van—loading这个组件来告诉用户正在加载。

主要代码为:

1.js部分:

/** * 页面的初始数据 */ data: { imgUrls : [ "/static/images/banner.jpeg", "/static/images/banner.jpeg" ], swiperWidth: 0, // 屏幕宽度 swiperHeight : 0, // 根据屏幕宽度等比例计算图片高度 buyList : [], // 限时抢购的数据 buyTime : "010226", // 限时抢购倒计时 list: [], // 首页商品列表数据 start : 0// 上拉加载的时候请求数据的起始点 }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { // 请求服务器,得到首页的数据 let _this = this; wx.request({ url: 'http://www.xiongmaoyouxuan.com/api/tab/1', method : "get", success : function(res){ console.log(res); _this.setData({ imgUrls: res.data.data.banners, buyList: res.data.data.topList, list: res.data.data.items.list.filter(function(item, index){ // 返回值为true,那么当前item就会保留,否则就过滤掉 return item.title != undefined; }) }) } }) // 根据屏幕宽度计算图片大小 let screenWidth = wx.getSystemInfoSync().screenWidth; this.setData({ swiperWidth: screenWidth, swiperHeight: screenWidth / 1080 * 400 }) // 调用倒计时方法 this.calcBuyTime(); // 每隔一秒调用一次函数 setInterval(this.calcBuyTime, 1000); }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { var _this = this; // 每一次上拉加载都是在之前的基础上+20 var st = this.data.start + 20; this.setData({ start : st }); wx.request({ url: 'http://www.xiongmaoyouxuan.com/api/tab/1/feeds?start='+this.data.start, method : "GET", success : function (res) { // 过滤调没有title的数据 var list = res.data.data.list.filter(function (item) { // 有title属性就保留,没有就被过滤掉 return item.title; }); // 当前请求下来的list添加到data的list里面去 var arr = _this.data.list.concat(list); // ... 指的是把数组展开成一系列逗号隔开的值 // var arr = [2,3,4,5]; // ...arr -- 2,3,4,5 // var arr = [..._this.data.list, ...list]; _this.setData({ list :arr }); } }) }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { }, calcBuyTime : function () { // 把时间调到下一个整点 var date = newDate(); var startTime = date.getTime(); date.setHours(date.getHours() + 1, 0, 0); var endTime = date.getTime(); var direction = parseInt((endTime - startTime)/1000); var seconds = direction % 60; var minutes = (direction - seconds) / 60; // 默认事下一个整点,所以小时数就是0 // 可以继续扩展,把小时数计算一下 var str = "00" + (minutes > 9 ? minutes : "0"+minutes) + (seconds>9 ? seconds : "0"+seconds); this.setData({ buyTime: str }); }, // 跳转详情页 onDetail : function (evt) { console.log(evt); var id = evt.currentTarget.dataset.id; wx.navigateTo({ url: '/pages/detail/detail?id='+id }) }})

2.json部分:

{ "usingComponents": { "van-button": "/dist/button/index", "van-card": "/dist/card/index", "van-loading": "/dist/loading/index" }}//引入vant库的各种组件

3.wxml部分:

<viewclass='page'> <viewclass='search'> <view>搜索</view> <view> <navigatorurl='/pages/search/search'>搜索商品</navigator> </view> </view> <swiper indicator-dots="true" autoplay="true" interval="3000" duration="500" circular="true" style="width:{{swiperWidth}}px; height:{{swiperHeight}}px" > <blockwx:for="{{imgUrls}}"> <swiper-item> <imagesrc="{{item.imageUrl}}"class="slide-image"/> </swiper-item> </block> </swiper> <view> <viewclass='buy-head'> <textclass='buy-title'>整点限时抢购</text> <viewclass='buy-time'> <text>{{buyTime[0]}}</text> <text>{{buyTime[1]}}</text> <textclass='icon'>:</text> <text>{{buyTime[2]}}</text> <text>{{buyTime[3]}}</text> <textclass='icon'>:</text> <text>{{buyTime[4]}}</text> <text>{{buyTime[5]}}</text> </view> </view> <scroll-view scroll-x style="width: {{swiperWidth}}px;" > <viewclass='buy-body'> <blockwx:for="{{buyList}}"> <viewclass='buy-item'> <viewclass='buy-image'><imagesrc='{{item.image}}'mode='aspectFit'></image></view> <view><textclass="van-ellipsis">{{item.title}}</text></view> <view><textclass="buy-price">¥{{item.price}}</text></view> </view> </block> </view> </scroll-view> </view> <viewclass='list'> <blockwx:for="{{list}}"> <van-card bindtap="onDetail" data-id="{{item.id}}" tag="{{item.couponValue}}" price="{{item.price}}" origin-price="{{item.originPrice}}" title="{{item.title}}" thumb="{{ item.image }}" > <viewslot="footer"> <van-buttonsize="mini">查看详情</van-button> <van-buttonsize="mini"type='danger'>加购物车</van-button> </view> </van-card> </block> </view> <viewclass='loading'> <van-loadingtype="spinner"color="#fff"/> </view> </view>

分类页

对于分类页的制作

1、请求所有分类title,显示在小程序顶部,使用vant组件库里的van-tabs组件。

2、默认第一个分类的数据请求下来然后做列表渲染

3、点击分类,绑定change事件,在事件里得到当前分类的索引值,通过索引值得到id请求当前分类的数据 “http://www.xiongmaoyouxuan.com/api/tab/ ” +id得到数据以后放在当前分类的detail里

4、分类的上拉加载:因为不同的分类都有自己的数据,所以每一种分类都有自己的start,所以在tabList里面每一个对象都有默认start=0,下拉的时候把当前这个分类的start += 20,去请求下20条数据,添加到当前分类的detail里。

具体代码为:

1.Js部分:

data: { tabList : [], // 分类的所有数据 tabIndex : 0// 当前正在查看的分类在tabList里的索引 }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { // 请求数据接口,得到tab列表 var _this = this; wx.request({ url: 'http://www.xiongmaoyouxuan.com/api/tabs', method: "GET", success : function(res){ console.log(res); _this.setData({ tabList : res.data.data.list.map(function(item){ // 给每一个分类加上start默认值为0 item.start = 0; return item; }) }); // 请求默认第一个分类的数据 wx.request({ url: 'http://www.xiongmaoyouxuan.com/api/tab/'+_this.data.tabList[0].id, method: "GET", success : function (res) { var list = res.data.data.items.list; console.log(list); // tabList里有多个title,每个title都有自己对应的详细商品数据 // 所以新增detail字段放到对应title的对象里 // 由于小程序里直接修改data的值不会立即生效 // 所以先取出来,修改完成以后再set回去 var tabList = _this.data.tabList; tabList[0].detail = list.filter(function(item){ // title存在,return true title不存在,return false return item.title; }); _this.setData({ tabList : tabList }); } }) } })onReachBottom: function () { var _this = this; // 得到当前分类的索引 var idx = this.data.tabIndex; // 使用索引取到当前分类的id var id = this.data.tabList[idx].id; // 把tabList取出来,设置当前分类的start,tabList set回去 var list = this.data.tabList; list[idx].start += 20; var start = list[idx].start; this.setData({ tabList : list }); // 请求当前分类的下20条数据 wx.request({ url: 'http://www.xiongmaoyouxuan.com/api/tab/'+ id +'?start=' + start, method : "GET", success : function (res) { // 得到后20条数据 // 到tabList的当前分类的detail里追加这20条 var list = _this.data.tabList; list[idx].detail = list[idx].detail.concat(res.data.data.items.list); console.log(res.data.data.items.list); _this.setData({ tabList : list }); } }) }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { }, onTabChange : function (evt) { var _this = this; // 得到当前分类的索引值,通过索引值取id // 通过当前id对应的接口去请求数据 console.log(evt.detail); var idx = evt.detail.index; // 修改当前tabIndex this.setData({ tabIndex : idx }); var id = this.data.tabList[idx].id; wx.request({ url: 'http://www.xiongmaoyouxuan.com/api/tab/'+id, method: "GET", success : function (res) { console.log(res.data.data.items.list); // 把tabLIst取出来赋值给list,然后修改list[idx].detail // 修改结束以后再把整个tabList setData回去 var list = _this.data.tabList; list[idx].detail = res.data.data.items.list; _this.setData({ tabList : list }); } }) }, onDetail: function (evt) { console.log(evt); var id = evt.currentTarget.dataset.id; wx.navigateTo({ url: '/pages/detail/detail?id=' + id }) }})

2.json部分:

{ //引入组件 "usingComponents": { "van-tab": "/dist/tab/index", "van-tabs": "/dist/tabs/index", "van-card": "/dist/card/index", "van-button": "/dist/button/index", "van-loading": "/dist/loading/index" }}

3.wxml部分:

<viewclass='page'> <van-tabsswipeableanimatedstickybind:change="onTabChange"> <blockwx:for="{{ tabList }}"> <van-tabtitle="{{item.name}}"> <blockwx:for="{{item.detail}}"wx:for-item="detail"> <van-card bindtap="onDetail" data-id="{{detail.id}}" tag="{{detail.couponValue}}" price="{{detail.price}}" origin-price="{{detail.originPrice}}" title="{{detail.title}}" thumb="{{ detail.image }}" > <viewslot="footer"> <van-buttonsize="mini">查看详情</van-button> <van-buttonsize="mini"type='danger'>加购物车</van-button> </view> </van-card> </block> </van-tab> </block> </van-tabs><viewclass='loading'> <van-loadingtype="spinner"color="#fff"/> </view></view>

总结

这些页面我都没有贴上.wxss的代码,因为大家喜欢的风格都不一样,样式自己调一下就好。其实这两个页面的逻辑都不是很难,主要就是从接口请求数据,然后自己把它渲染出来。主要是有些知识没学过,就不知道怎么弄,但是只要会用那些方法,这两个页面就没什么难度。

更多精彩文章:

算法|从阶乘计算看递归算法

算法|字符串匹配(查找)-KMP算法

JavaScript|脚本岂能随意放置

开发|优秀的Java工程师的“对象”一定不错

谈一谈|2019蓝桥杯回顾与分享

where2go 团队


微信号:算法与编程之美

温馨提示:点击页面右下角“写留言”发表评论,期待您的参与!期待您的转发!

原文发布于微信公众号 - 算法与编程之美(algo_coding)

原文发表时间:2019-04-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券