内容简介:hello大家好,这是我的第一篇掘金文章,每天都在掘金上面看各位大佬的文章,终于鼓足勇气决定写一篇属于自己的文章了。今天呢,就给大家带来一篇微信小程序(麦当劳点餐)+爬虫的详解吧。大佬们可以忽略我这个小辣鸡,但是如果你也是前端小白的话,可以认真看看哟,说不定对你有帮助呢。这个小程序是为最近参加的一个小活动而制作的(为期两天,3-4人组队,完成一个小型项目)。说实话,两天怎么可能完成一个小程序呢?在前两天,我们大致完成了小程序基本结构,然后由我完成收尾工作,前前后后历时四天。大家可以看到,这个小程序有四个页面
hello大家好,这是我的第一篇掘金文章,每天都在掘金上面看各位大佬的文章,终于鼓足勇气决定写一篇属于自己的文章了。今天呢,就给大家带来一篇微信小程序(麦当劳点餐)+爬虫的详解吧。大佬们可以忽略我这个小辣鸡,但是如果你也是前端小白的话,可以认真看看哟,说不定对你有帮助呢。
项目介绍
这个小程序是为最近参加的一个小活动而制作的(为期两天,3-4人组队,完成一个小型项目)。说实话,两天怎么可能完成一个小程序呢?在前两天,我们大致完成了小程序基本结构,然后由我完成收尾工作,前前后后历时四天。
项目预览图
大家可以看到,这个小程序有四个页面。
项目工作分配
由于我是组长,所以工作的内容是由我分配的,我们组内四个成员,正好一人一个页面,但是页面有简单和复杂之分的,在我的暴政下,分到了复杂页面的也不许抱怨!当然我是一个好组长,我给自己分配了选餐的页面并且爬虫爬数据也由我完成。所以下面我给大家分享的就是我完成的那个页面。
项目开始前的准备
一些准备工作:
- 申请账号:进入微信公众平台根据指示申请注册账号
- 开发工具:VScode和微信开发者工具
- 小程序官方文档
- github申请存储库
使用的一些工具:
- 小程序云开发数据库功能
- 微信官方文档
- markMan(可以进行图片测量和标注的工具)
- iconfont(阿里巴巴矢量图标库,有大量icon资源)
- github(由于这是我们一个小组完成的项目,所以需要建一个新的存储库,然后把大家拉进来)
这里需要着重说明一下github命令行的操作,一个人开发的时候,直接git push就行。但是多人合作开发的时候,是不能直接git push的,如果别人先提交了项目,然后你再提交之前一定先要git pull,先把别人的项目拉下来,然后在git push,不然会导致冲突。
其实除了这些基本的准备工作以外,我们最应该做的就是思考。有一位前辈曾经告诉我,在接手项目的时候,不应该第一时间就去敲代码,而是应该闭上眼睛思考一会。具体思考什么,他也没有细说,但是通过这次,我领悟到了前辈的意思。首先,我们需要仔细的看一下设计稿,在脑子里搭建起来大致的框架,以便在写代码的时候,可以提升效率。其次,我们应该思考数据如果存放,打个比方:在做电商页面的时候,点击左边导航栏,右边内容框显示相应的数据,这就涉及到数据的存放了。所以在写代码之前,我们就应该思考好这些逻辑。
项目完成过程
下图就是我要完成的页面。
第一开始看见这个页面的时候,心里其实并不慌,因为之前也做过一些电商的小程序,所以知道这个页面的基本功能应该如何实现,所以在写代码的过程中,还算很顺利。
点餐页面
当看见这个页面的时候,脑子里大致就需要搭建一个结构框架。
- 页面上端是一个swiper,用于滚动不同的广告。
- 页面中间的部分是地址栏,点击可以选择不同的商店。
- 页面中下部是一个点餐栏,左边和右边同时都要使用scroll-view。
- 尾部是一个类似于购物车的东西,这一部分建议大家写成一个组件调用,为了减少代码耦合度。(虽然我没用组件)
话不多说,下面来分析结构吧!
首先我们来看一下页面的swiper部分
可以从图片看出,这是一个广告位置,用于放置最新的产品,这一部分其实很简单,直接引用小程序的swiper组件即可。
<swiper indicator-dots="true" indicator-active-color="rgba(242,207,4,1)" autoplay="true" circular="true" interval="4000" duration="1000" class="header" wx:if="{{hidden}}"> <swiper-item wx:for="{{adImage}}" wx:key="index"> <image mode="aspectFill" class="headerImg" src="{{item.image}}" /> </swiper-item> </swiper> 复制代码
这一部分代码如上,需要提一下的就是swiper组件里面indicator-active-color这个属性只接受rgba形式,不接受十六进制颜色的输入,大家可以自行在百度上面找转换的方法。
接下来就是地址栏的部分
我这里放两张图片,方便对比:
这一部分的页面并不算简单,首先外面的大盒子需要设置为弹性布局,方便左边的地址栏,还有右边的会员并排在一排。然后地址栏也需要设置为弹性布局,将flex-flow设置为column就可以沿Y轴分布,然后将align-items: center;就可以把店名还有地址放在方框中间。因为这个地址栏是可以点击切换地址的,所以内边距不可以写死,只能用弹性布局将它们放在中间,如果选择的地址过长的话,页面也会自动调整边距,十分的美观。
<!-- 地址栏 --> <view class="middle" wx:if="{{hidden}}"> <navigator style="display: inline-block" target="" url="../index/index" hover-class="navigator-hover"> <view class="address"> <view> <view class="storeName">{{storeInfo.name}}</view> <view class="storeAdress">{{storeInfo.address}}</view> </view> </view> </navigator> <view class="member"> <image src="../../images/menuImg/u=324093054,273186418&fm=26&gp=0.jpg" class="menberImg" /> <text class="memberText">会员中心</text> </view> </view> 复制代码
.middle{ height: 110rpx; width: 100%; background-color: #fff; display: flex; border-bottom: 1px solid #eeeeee; } .address{ width: 600rpx; height: 110rpx; display: flex; align-items: center; border-right: 1px solid #eeeeee; } .storeName{ line-height: 40rpx; font-size: 28rpx; font-weight: bold; margin-left: 40rpx; } .storeAdress{ line-height: 34rpx; font-size: 22rpx; color: #737373; margin: 0 40rpx; } .member{ width: 150rpx; height: 110rpx; padding: 16rpx 0; box-sizing: border-box; display: flex; flex-flow: column; align-items: center; } .menberImg{ width: 40rpx; height: 40rpx; border-radius: 50%; margin: 0 ; } .memberText{ position: relative; width: 100%; font-size: 24rpx; line-height: 24rpx; text-align: center; margin-top: 14rpx; } 复制代码
因为这里是有一个点击事件的,点击过后,跳转到选地址页面,然后选完地址在跳转回本页面。那么在页面与页面之间是怎么传递数据的呢?在逛了一圈小程序开发文档之后,我们发现了一个api十分的好用,可以将页面的数据暂时放入缓存区,以一个key来命名,然后在另外一个页面,也用相同的key来获取,就可以获取缓存区的数据了,下面来看看代码吧。
toDetail (e) { let idx = e.currentTarget.dataset.idx; if (idx) { wx.setStorage({ key:"itemsIndex", data: this.data.items[idx], }) } else { wx.setStorage({ key:"itemsIndex", data: this.data.items[0] }) } wx.navigateTo({ url: '../menu/menu' }) }, 复制代码
这是通过另外一个页面跳转我的页面的点击事件,用wx.setStorage来存取数据。
wx.getStorage({ key: 'itemsIndex', success: (res) => { let storeInfo = this.data.storeInfo; storeInfo.name = res.data.name; storeInfo.address = res.data.address; // console.log(storeInfo); this.setData({ storeInfo }) }, fail: () => {}, complete: () => {} }); 复制代码
这是在本页面接收数据的方法,并且这个方法要写在onLoad生命周期函数里,这样就可以在页面加载的时候把获取到的数据渲染到页面上。
然后就是本页面含金量最高的部分了
这一部分,应该是所有电商小程序都会用到的。其实说难也不难,说简单也不简单,只要认真看完我下面的讲解,应该就了解要怎么做了。
相信大家看到这个截图之后,内心都有一些自己的想法,那不妨继续看看我的做法,然后与你们自己的想法融合在一起,看看是不是会迸发出新的火花呢!
<!-- 选餐栏 --> <view class="menuContent"> <view class="scrollLeft"> <scroll-view scroll-y> <navigator class="search" url="../" hover-class="none"> <image class="searchImage" src="../../images/menuImg/sou-suo.png" /> <text class="searchText">搜索</text> </navigator> <block wx:for="{{scrollLeft}}" wx:key="index"> <view class="{{curIndex === index ? 'selected' : 'select'}}" bindtap="onSelect" data-index="{{index}}" data-id="{{item.id}}"> <image src="{{item.url}}" class="selImg" wx:if="{{curIndex === index}}" /> <view class="{{curIndex === index ? 'selectedText' : 'selectText'}}"> {{item.name}} </view> </view> </block> </scroll-view> </view> <view class="scrollRight"> <scroll-view scroll-y scroll-into-view="{{toView}}" scroll-with-animation="true" bindscroll="scrollTop" style="height: 1205rpx"> <block wx:for="{{scrollRight}}" wx:key="index"> <view class="food" wx:for="{{item.detail}}" wx:key="index" wx:for-item="food" id="{{item.id}}"> <view class="foodName">{{food.name}}</view> <view class="foodPrice"> ¥ <view class="foodPriceNum">{{food.price}}</view> 起* </view> <image src="{{food.img}}" class="foodPci" /> <view class="custom"> <view class="customText">去定制</view> <navigator url="../cart/cart" hover-class="none"> <view class="customBtn" bindtap="gotoCart" data-id="{{item.id}}" data-index="{{index}}"> <image src="../../images/menuImg/toRight.png" class="customPic" /> </view> </navigator> </view> <view class="order"> <view class="orderText">大套餐</view> <view class="orderselect" wx:if="{{food.showCombo}}"> <view class="reduce" bindtap="OnReduce" data-id="{{item.id}}" data-index="{{index}}"> <image src="../../images/menuImg/jianhao.png" class="orderPic" /> </view> <text class="orderTitle">{{food.title}}</text> <view class="add" bindtap="OnAdd" data-id="{{item.id}}" data-index="{{index}}"> <image src="../../images/menuImg/jiahao.png" class="orderPic" /> </view> </view> <view class="orderBtn" wx:else bindtap="OnAdd" data-id="{{item.id}}" data-index="{{index}}"> <image src="../../images/menuImg/jiahao.png" class="orderPic" /> </view> </view> </view> </block> </scroll-view> </view> </view> 复制代码
从页面结构可以看出,这一部分分为左边和右边两部分,然后都通过wx:for循环,将数据循环渲染在页面上,左边和右边也都使用了scroll滚动条,这里有一个坑不知道大家是否踩过,就是使用小程序scroll-view组件时,必须要给这个组件设置固定的高度或者宽度(这采决与你是设置了Y方向滚动还是X方向滚动),如果不设置高度的话,滚动条就会失效,虽然这个坑我已经踩过很多次了,但是每当我遇到时,都还会在踩一遍。
这里由于css太多了,所以就不放上来了展示给大家看了,如果有想看朋友可以去文章最下面的github地址观看。在css里也有一个坑,那就是在选择布局的时候有两种方法,第一种是使用弹性布局,将左边导航栏和右边选餐栏并排一起。第二种是使用display: inline-block;方法,使得左边导航栏和右边选餐栏都变成行内块元素,并排在一起,虽然布局上面没问题,但是当循环数据时,你就会发现右边的数据会倒叙排列,我也没有找到会导致这种方法的原因。所以遇到左右两边需要并排且需要填充数据的时候,推荐使用弹性布局。
接下来就是最最最最难的逻辑部分了,我会给大家分左边和右边来讲解。虽然百度上面也有很多左右联动的逻辑方法,但是百度到的答案不尽人意,所以我就取其精华去其糟粕,写了一下自己的逻辑,接下来我就要给大家细致的讲一下左右联动的效果实现。
我们先来看看点击左边导航栏,然后点击的导航栏变换样式是怎样实现的。
onSelect(e) { console.log(e); const that = this; const curIndex = e.currentTarget.dataset.index; const toView = e.currentTarget.dataset.id; console.log(toView) that.setData({ curIndex, toView }) }, 复制代码
这里通过点击事件,获取到该数据的index并赋值给curIndex,然后通过判断class="{{curIndex === index ? 'selected' : 'select'}}"改变样式。同时点击事件时,也将数据里的id值赋给toView,然后在右边的滚动条里,设置scroll-into-view="{{toView}}",通过这个属性,滚动条就可以自动跳转到对应的toView数据里。这是小程序自定义的方法,可以很方便的做到点击左边,右边自动跳转的操作。但是滚动右边,左边样式也自动切换就不是那么容易的事情了。
.then(res => { let heightArr = []; const height = 180; let heightList = 0 for(let i = 0; i < res.length; i++) { heightList += res[i].detail.length * height; heightArr.push(heightList); } // console.log(heightArr); this.setData({ heightArr }) }) 复制代码
在这里,我是在onLoad生命周期函数里,先请求数据,通过.than接收到数据,const height = 180;这是我设置的每一个食物框的固定高度,所以通过这个高度乘以分类里面的每个数据,就可以获得右边滚动条不同分类的高度区间,然后存入heightArr数组。
scrollTop(e) { // console.log(e) const scrollTop = e.detail.scrollTop; if(scrollTop > 100) { this.setData({ hidden: false }) } else{ this.setData({ hidden: true }) } const heightArr = this.data.heightArr; for(let i = 0; i < heightArr.length; i++) { if(scrollTop > 0 && scrollTop < heightArr[0]) { this.setData({ curIndex: 0 }) } else if (scrollTop < heightArr[i] && scrollTop > heightArr[i - 1]) { this.setData({ curIndex: i }) } } }, 复制代码
右边高度的区间我们已经得到了,然后我们应该怎么利用好它呢?在scroll-view组件里,有一个bindscroll="scrollTop"方法是滚动滚动条时可以触发的事件,这个方法可以获取到滚动的顶部在滚动时距离顶部的距离。那么我们就可以利用这个滚动的距离,然后获取到这个距离在heightArr区间的哪一部分,然后将这个区间的索引值赋值给curIndex。 这样左边的样式就能随右边滚动而改变了。这个方法大家学会了嘛,如果没有看懂,可以在下面评论区问我哟!
OnAdd(e) { const id = e.currentTarget.dataset.id; const indexSelect = e.currentTarget.dataset.index; let totalPrice = this.data.totalPrice; let index = id.split('l')[1]; let scrollRight = this.data.scrollRight; const price = scrollRight[index].detail[indexSelect].price; scrollRight[index].detail[indexSelect].title++; scrollRight[index].detail[indexSelect].showCombo = true; totalPrice = totalPrice + price; this.setData({ scrollRight, totalPrice }) }, OnReduce(e) { const id = e.currentTarget.dataset.id; const indexSelect = e.currentTarget.dataset.index; let index = id.split('l')[1]; let scrollRight = this.data.scrollRight; let title = scrollRight[index].detail[indexSelect].title; let totalPrice = this.data.totalPrice; const price = parseFloat(scrollRight[index].detail[indexSelect].price); totalPrice = totalPrice - price; if(title > 1) { scrollRight[index].detail[indexSelect].title--; this.setData({ scrollRight, totalPrice }) }else if(title = 1) { scrollRight[index].detail[indexSelect].title--; scrollRight[index].detail[indexSelect].showCombo = false; this.setData({ scrollRight, totalPrice, }) } }, 复制代码
上面是一些简单的加和减的方法,点击+号的时候,触发onAdd事件,获取到当前点击事件的索引值,然后找到数据里面每一项的价格,以及数量,除了将数量+1之外,还需要算出当前所有物品的总价。点击-号的方法一样,我就不再赘述了。
最后就是页面下端的购物车部分了
当选餐时,就会自动跳出购物车按钮,然后点击购物车,就会显示出购物清单列表,在购物清单列表中,也可以增加或者减少食物。
<view class="shoppingList" wx:if="{{showList && totalPrice != 0}}"> <view class="shadow" bindtap="onList"></view> <view class="shoppingBottom"> <view class="shoppingHeader"> <view class="hasSelected"> <image src="../../images/menuImg/shoppingGray.png" class="image" /> <view class="text">已选产品</view> </view> <view class="empty" bindtap="onEmpty"> <image src="../../images/menuImg/lajitong.png" class="image" /> <view class="text">清空</view> </view> </view> <scroll-view scroll-y style="max-height: 534rpx"> <block wx:for="{{scrollRight}}" wx:key="index"> <view class="shoppingBody" wx:for="{{item.detail}}" wx:for-item="food" wx:if="{{food.showCombo}}" wx:key="index"> <view class="name">{{food.name}}</view> <view class="unitPrice"> ¥ <view class="unitPriceNum">{{food.price * food.title}}</view> </view> <view class="orderselect addPlace"> <view class="reduce" bindtap="OnReduce" data-id="{{item.id}}" data-index="{{index}}"> <image src="../../images/menuImg/jianhao.png" class="orderPic" /> </view> <text class="orderTitle">{{food.title}}</text> <view class="add" bindtap="OnAdd" data-id="{{item.id}}" data-index="{{index}}"> <image src="../../images/menuImg/jiahao.png" class="orderPic" /> </view> </view> </view> </block> </scroll-view> </view> </view> <!-- 选好了 --> <view class="shopping" wx:if="{{totalPrice != 0}}"> <view class="shoppingLeft"> <view class="shoppingCar" bindtap="onList"> <image src="../../images/menuImg/shopping.png" class="shoppingImg" /> </view> <view class="shoppingPrice"> <view class="priceTitle">¥</view> <view class="priceNum">{{totalPrice}}</view> </view> </view> <navigator url="../settlement/settlement" class="shoppingRight" bindtap="gotoSettlement" > <view class="rightText">选好了</view> <image src="../../images/menuImg/yellowRight.png" class="rightImg" /> </navigator> </view> 复制代码
这是购物清单还有购物车的部分,使用position: fixed;将这部分固定在屏幕的底部,不会随着屏幕滑动而滑动,在结构上面,还设置了一个蒙层,当展示购物清单时显示。
// 是否显示选餐列表 onList() { let showList = this.data.showList; showList = !showList; this.setData({ showList }) }, // 清空事件 onEmpty() { const scrollRight = this.data.scrollRight; for(let i = 0; i < scrollRight.length; i++) { for(let j = 0; j < scrollRight[i].detail.length; j++) { scrollRight[i].detail[j].title = 0; scrollRight[i].detail[j].showCombo = false; } } this.setData({ scrollRight, totalPrice: 0, showList: false }) }, // 跳转到cart页面 gotoCart(e) { // console.log(e) const id = e.currentTarget.dataset.id; const indexSelect = e.currentTarget.dataset.index; let index = id.split('l')[1]; let scrollRight = this.data.scrollRight; const zhushi = scrollRight[index].detail[indexSelect]; console.log(zhushi); wx.setStorage({ key: "cartFood", data: zhushi }) }, 复制代码
这些方法都是基本方法,还是很简单的,大家看一下应该就知道做什么的了,也不再一一介绍了。
啊啊啊啊啊啊啊啊啊啊,好累,码了这么多字,感觉写文章比写小程序还累!但是我不能停下来,因为还有重点没有讲!
接下来就是这篇文章的重点部分了,小伙伴们快竖起耳朵听啊!
爬虫爬取数据
相信大家在写小项目的时候,最头疼的就是写假数据了,每次编写假数据,自己看的都头皮发麻。所以我给大家带来一个简单的爬虫,不仅可以轻轻松松的获取到数据,而且显得既高端又专业!
我把爬虫写在了云函数里,这样可以直接在运行云函数的时候,就把爬虫爬取到的数据直接存储到云数据库。在写爬虫之前,首先需要将运行环境初始化成node运行环境,然后下载基本的依赖,以便后面可以在网页上获取数据。因为我这里要获取到的数据在不同的页面里,所以我先将网页全部定义好,方便直接引用。同时我也创建了不同的空数组,为了将从不同网页中获取到的不同数据存入不同的数组里。这些准备工作都做完了,下面来看看代码吧。
const cloud = require('wx-server-sdk'); const request = require('request'); const cheerio = require('cheerio'); const breakfast = 'http://www.5ikfc.com/mdl/menu/breakfast/'; //早餐 const chaozhitaocan = 'http://www.5ikfc.com/mdl/menu/chaozhitaocan/'; //超值套餐 const happymeals = 'http://www.5ikfc.com/mdl/menu/happymeals/'; //快乐套餐 const sides = 'http://www.5ikfc.com/mdl/menu/sides/'; //配餐 const drink = 'http://www.5ikfc.com/mdl/menu/drink/'; //饮料 const dessert = 'http://www.5ikfc.com/mdl/menu/dessert/'; //甜品 const mccafe = 'http://www.5ikfc.com/mdl/menu/mccafe/'; //麦咖啡 let breakfastList = []; let chaozhitaocanList = []; let happymealsList = []; let sidestList = []; let drinkList = []; let dessertList = []; let mccafeList = []; // 初始化 cloud cloud.init() const db = cloud.database(); function maidanglaoSpider(http, list) { return new Promise((resolve, reject) => { request(http, (err, res) => { if(err) { reject('net error'); } if(!err) { const body = res.body; const $ = cheerio.load(body, { decodeEntities: false }) $('.lside.fr.bdgrey.main_wrap .fx li') .each(function() { const img = $('a img', this).attr('src'); const name = $('a', this).text().trim(); const price = $('b', this).text().trim(); list.push({ name, img, price }) console.log({ name, img, price }) }) resolve(list); } }) }) } maidanglaoSpider(breakfast,breakfastList) .then(res => { console.log(res); }) 复制代码
首先往爬虫函数里传http和list两个参数,因为我需要将不同网页的数据存入不同的list里面。然后函数return一个Promise函数,然后在promise函数里发起请求,如果请求没有报错的话,就const body = res.body获取网页的html的body结构,然后通过 ('a img', this).attr('src');获取我们需要的图片的src;通过const name = ('b', this).text().trim();获取到需要的价格。最后将这三个数据以对象的形式push进数组,然后resolve出来。到这里我们的爬虫函数就写好啦,然后下面就需要把数据传入云数据库了。
exports.main = async (event, context) => { const breakfastData = await maidanglaoSpider(breakfast, breakfastList); const chaozhitaocanData = await maidanglaoSpider(chaozhitaocan, chaozhitaocanList); const happymealsData = await maidanglaoSpider(happymeals, happymealsList); const sidesData = await maidanglaoSpider(sides, sidestList); const drinkData = await maidanglaoSpider(drink, drinkList); const dessertData = await maidanglaoSpider(dessert, dessertList); const mccafeData = await maidanglaoSpider(mccafe, mccafeList); let arrData = [breakfastData,chaozhitaocanData,happymealsData,sidesData,drinkData,dessertData,mccafeData] for(let i = 0; i < arrData.length; i++) { await db.collection('food').add({ data: { id: i, detail: arrData[i] } }) } } 复制代码
我首先将不同的数据命名好,然后将他们放进arrData数组里,然后通过遍历这个数组,把每一项数据都存入云函数里。
云数据库内容如下
当我同一个小组的大佬看到我的云数据库以后,对我进行了夸赞:“您真是将数据库运用到了极致。”当然了,这并不是夸赞,而是无情的嘲讽。我在存数据的时候,将所有数据存在了一个集合中,并且在集合中将数据划分开来(这是极度错误的做法,希望大家不要效仿我),由于这是我第一次使用云数据库存数据,所以犯这种错误也能体谅。
正确做法是:将每一个种类的数据,存放在一个集合中,不要吝啬数据库的使用。
获取数据
上面我们已经把爬虫的数据存进云函数了,然后就到了获取数据的时候了。
wx.cloud.callFunction({ name: 'foodData', success: (res) => { // console.log(res); db.collection('breakfast') .get() .then(res => { let food = {}; food.id = `l${res.data[0].id}` food.detail = res.data[0].detail.slice(0,5); food.title = 0; let scrollRight = this.data.scrollRight; scrollRight.push(food); this.setData({ scrollRight }) return res }) .then(res => { let food = {}; food.id = `l${res.data[1].id}` food.detail = res.data[1].detail.slice(0,5); food.title = 0; let scrollRight = this.data.scrollRight; scrollRight.push(food); this.setData({ scrollRight }) return res }) .then(res => { let food = {}; food.id = `l${res.data[2].id}` food.detail = res.data[2].detail.slice(0,5); food.title = 0; let scrollRight = this.data.scrollRight; scrollRight.push(food); this.setData({ scrollRight }) return res }) .then(res => { let food = {}; food.id = `l${res.data[3].id}` food.detail = res.data[3].detail.slice(0,5); food.title = 0; let scrollRight = this.data.scrollRight; scrollRight.push(food); this.setData({ scrollRight }) return res }) .then(res => { let food = {}; food.id = `l${res.data[4].id}` food.detail = res.data[4].detail.slice(0,5); food.title = 0; let scrollRight = this.data.scrollRight; scrollRight.push(food); this.setData({ scrollRight }) return res }) .then(res => { let food = {}; food.id = `l${res.data[5].id}` food.detail = res.data[5].detail.slice(0,5); food.title = 0; let scrollRight = this.data.scrollRight; scrollRight.push(food); this.setData({ scrollRight }) return res }) .then(res => { let food = {}; food.id = `l${res.data[6].id}` food.detail = res.data[6].detail.slice(0,5); food.title = 0; let scrollRight = this.data.scrollRight; scrollRight.push(food); console.log(food); this.setData({ scrollRight }) return res }) 复制代码
本来我想的是利用循环,把数据遍历出来,然后通过循环存进定义的空数组里。但是我怎么也存不进去,实在找不到原因,我就把数据的每一项都单独拎出来然后存进去。虽然代码很不美观,但是总算把数据存进去了。这个函数要写在onLoad生命周期函数里,这样可以在页面加载的时候就把数据获取到,然后渲染到页面上。
至此,我的个人页面就完成了,小伙伴们也将他们的页面提交到了github上面,本以为工作就结束了,可以高高兴兴的玩耍了。但是转头一想,页面跳转的工作还没人做呢,哎,谁让我是小组长呢,只能由我这个“老父亲”来做收尾工作了。
收尾工作
其实收尾工作很简单,就是改一下路由跳转,并且传送一下对应的数据就行。
传送和接收数据代码如下:
wx.setStorage({ key:"itemsIndex", data: this.data.items[idx], }) wx.getStorage({ key: 'itemsIndex', success: (res) => { let storeInfo = this.data.storeInfo; storeInfo.name = res.data.name; storeInfo.address = res.data.address; // console.log(storeInfo); this.setData({ storeInfo }) }, fail: () => {}, complete: () => {} }); 复制代码
在跳转页面时,利用wx.setStorage将数据放入缓存区,然后在需要数据的页面,利用wx.getStorage获取缓存区的数据。
好啦,工作算是结束了,给大家来看看我们的最终成果把!
嘿嘿,总体来说,还算过得去吧
一些总结
小程序写完了,总得有一些工作总结对吧,我觉得通过这次几个小伙伴通力合作,我感慨还是蛮多的,给大家总结一下几点吧!
- 第一!最重要的就是!心平气和。几个小伙伴合作写项目,难免在一些观点上面有分歧,但是大家一定要心平气和的商讨,不能各执己见。虽然我们团队在写项目的时候也有几句争吵,但是总体来说还算平和。
- 第二!一定要注意代码的质量,以前一直是一个人写代码,没有体会到代码质量的重要性,但是通过这次合作,我发现代码一定要写的简单易懂,也要多写注释,这样方便别人修改你的代码,同时也方便自己阅读。
- 第三!一定要坚持,有些事情看似很难,但是只要坚持下来,你会发现那些困难,再一点点土崩瓦解,到最后会被你完全击溃。
- 第四!不懂就问,不管是老师,同学,还是百度,不懂就要去问,不能把问题放在那里不解决,只要多问多思考,就会一点点有思路了。
以上几点就是这次小项目完成的总结啦,同时也是这篇文章的收尾了,这篇文章是我第一次写文章,所以我知道可能很差,所以大家有什么建议的话,一定要给我留言,方便我改进,同时如果大家对这个项目有什么不懂的,也可以在留言区问,我会细心解答的!
这是这个项目的github地址: github.com/Yeqing98/Ma… (有需要的小伙伴可以拿去参考一下噢!)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Python3网络爬虫(十一):爬虫黑科技之让你的爬虫程序更像人类用户的行为(代理IP池等)
- 50行代码实现一个并发的 Python 爬虫程序
- 博彩骗局、违法爬虫:程序员还要警惕哪些“深坑”?
- 王者程序员整理的Python网络爬虫和web的系统学习路线图
- 爬虫需谨慎,那些你不知道的爬虫与反爬虫套路!
- 反爬虫之字体反爬虫
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Visual Thinking
Colin Ware / Morgan Kaufmann / 2008-4-18 / USD 49.95
Increasingly, designers need to present information in ways that aid their audiences thinking process. Fortunately, results from the relatively new science of human visual perception provide valuable ......一起来看看 《Visual Thinking》 这本书的介绍吧!
RGB转16进制工具
RGB HEX 互转工具
html转js在线工具
html转js在线工具