手机微信小程序(仿美团)
初见小程序,为它的娇小玲珑所吸引住,不由自主突发奇想。这并不恰好是客户所必须的吗?既省时省力,又不占手机运行内存。所以我下决心一定要做出一个自身的小程序,随后赚钱、赚钱、赚钱...自然如今仅仅学习培训环节,因此先仿一个顶级设备来挑战自我吧。说到高档,当然殊不知的就想起了美团外卖。以后噼噼啪啪一顿忙乎,总算做出了一点模样来,期待能为同是新手的学生们提供一点协助和参照,如今大家步入主题。
开发环境微信web微信开发工具: 官方网站就可以下载,坚信我们早已安裝好了吗。小程序 API: 官方网站提供的文本文档,不明白地区多看看二遍大部分就可以解决了。Easy Mock: 一个可以提供虚似api接口的网站,在前面独自一人开发设计的情形下,确实是最好不过的道具了。功能早已完成的功能:主界面订单信息界面客户界面点餐界面精准定位界面未完成的功能:数都数不尽,终究大型企业的商品,不是说效仿就模仿的,因此只完成了一些关键的功能,和一些工作能力以内的功能...新项目运行建立界面:"pages":[ "pages/home/home", "pages/menu/menu", "pages/location/location", "pages/my/my", "pages/order/order" ],只需编写app.js中的pages属性,便会在新项目文件目录下的pages文件夹里自动生成一个文件夹名称,里吐司面包扩了.wxml 、 .wxss 、 .json 、 .js那样四个文档。wxml便是界面构造文档, .wxss便是款式文档, .js是用于储放js代码并完成界面逻辑性的地区,对于 .json便是用于配备网页页面特性的地区,如:改动菜单栏的色调,和文本。
配备菜单栏的款式:"window":{ "navigationBarTitleText": "美团 ", "navigationBarTextStyle": "white", "navigationBarBackgroundColor": "#FFC ** 0" },一样是在app.json中配备,别的网页的菜单栏都为此为例子。
加上底栏:"tabBar": { "color": "#272636", "selectedColor": "#FFD161", "backgroundColor": "#fff", "borderStyle": "#a8a8a8", "list": [ { "pagePath": "pages/home/home", "iconPath": "pages/i ** ges/home.png", "selectedIconPath": "pages/i ** ges/home-selected.png", "color":"white", "text": "主页" }, { "pagePath": "pages/order/order", "iconPath": "pages/i ** ges/order.png", "selectedIconPath": "pages/i ** ges/order-selected.png", "text": "订单信息" }, { "pagePath": "pages/my/my", "iconPath": "pages/i ** ges/my.png", "selectedIconPath": "pages/i ** ges/my-selected.png", "text": "我的" } ] }在app.json中撰写以上编码,这也是小程序内置的功能,只必须生搬硬套照搬就可以了,极为便捷,实际效果如下所示:
数据信息要求/** * 性命周期函数--监视网页页面表明 */ onShow: function () { var that = this; wx.request({ url: "https:// ** .easy-mock.com/mock/596257bc9adc231f357c46 ** /restaurant/info",//easy-mock转化成的虚似api接口连接 method: "GET", success: function (res) {//取得成功获得数据信息,对数据资料完成解决 that.setData({//将信息发送至data中 restaurant: res.data.data.restaurant, location: wx.getStorageSync('location') }) } }); },data是每一个网页页面.js文件里都具有的一个键,用于存储本网页页面必须运用的数据信息。实际应用,可在wxml文件选用{{'data中的键名'}}的方式启用数据信息。虚似数据信息大概如下所示:
{ "success": true, "data": { "restaurant": [{ "name": "御膳坊", "src": "http://i2.kiimg.com/601998/a955867016875a41.jpg", "star": 4.5, "sales": ** 1, "initial_price": 0, "distribution_price": 0, "distance": "156m", "time": 33 }, { "name": "炸鸡啤酒屋", "star": 4.5, "sales": 731, "src": "http://i4.piimg.com/601998/9ce47f2f19d7717d.jpg", "initial_price": 15, "distribution_price": 0, "distance": "1.3km", "time": 52 },{ //省去 },{ //略去 },{ //... }] }}主界面设计效果图:
swiper控制运用最先是好几页标识的滚动转换,这儿应用的是swiper,它是一款小程序内置的滚轮部件,应用把握起來比较简单,实际编码如下所示:
<swiper class="categoryList" indicator-dots="true" indicator-color="rgba(228,228,228,1)" indicator-active-color="#FECA49"> <block wx:for="{{categoryList}}" wx:key=""> <swiper-item> <block wx:for="{{item}}" wx:key=""> <view class="category-info"> <i ** ge src="{{item.src}}" class="category-i ** ge"></i ** ge> <view class="category-text">{{item.name}}</view> </view> </block> </swiper-item> </block> </swiper>swiper标签便是滚轮部件的行为主体,表明可以滚动的地区,在其中indicator-dots属性是设定设置点是不是表明。下面swiper-item标签在swiper当中表明的是每一个用于做为滚动的网页页面。这儿用包囊着swiper-item表明的是应用categoryList对象数组中数据来循环系统3D渲染swiper-item,swiper-item的数目在于categoryList中有多少组数据信息。以后在swiper-item中的block标识表明的是在一个网页页面选用categoryList.item中的数据信息循环系统3D渲染好几个相近的标识,这种标识便是设计效果图中的类型项,一共好几页,每张八个。这就是swiper和循环系统3D渲染的一些基本上使用方法。
弹出来层的完成<view class=" ** sk"hidden="{{ ** sk2Hidden}}" bindtap=" ** sk2Cancel"> <template is="sort_list" data="{{selected,sortSelected}}"/> <scroll-view class="filterList" scroll-y="true" > <view class="filterList-characteristic-title">店家特点</view> <view class="filterList-characteristic-items"> <block wx:for="{{characteristicList}}" wx:key=""> <view class="filterList-characteristic-item {{characteristicSelected[index]==true?'characteristic-selected':''}}" catchtap="characteristicSelected" data-index="{{index}}">{{item.text}}</view> </block> </view> <view class="filterList-discount-title">优惠活动(单选)</view> <view class="filterList-discount-items"> <block wx:for="{{discountList}}" wx:key=""> <view class="filterList-discount-item {{discountSelected==index?'discount-selected':''}}" catchtap="discountSelected" data-index="{{index}}"> <text class="filterList-discount-item-icon" style="background:{{item.iconColor}}">{{item.icon}}</text> {{item.text}}</view> </block> </view> </scroll-view> <view class="filterList-footer"> <view class="filterList-footer-delect" catchtap="clearSelectedNumb">清除筛选</view> <view class="filterList-footer-finish" bindtap="finish">完成 <view class="filterList-footer-finish-number" hidden="{{selectedNumb==0}}">{{selectedNumb}} </view> </view> </view></view>最外层的 ** sk类的view就是一个遮罩层,用来覆盖之前的界面形成遮罩的效果,并在上面显示新的界面也就是弹出层。以上的代码就是效果图中点击筛选按钮所呈现出来的内容了。其中bindtap属性就是点击事件的绑定了,具体的点击事件需要在.js文件中设置。值得一提的是,bindtap事件是会把当前标签受到的点击冒泡给它的父容器,这就相当与同时点击了他的父容器,如果想阻止冒泡的话就需要使用catchtap。
定位界面先上效果图:
页面结构:
<view class="header"><view class="search-input"> <input placeholder="请输入收货地址" bindinput="input"></input> </view> <view class="search-btn">搜索</view></view><view class="result-container" hidden="{{hidden}}"><scroll-view scroll-y="true"class="search-result-list" hidden="{{hidden}}"> <block wx:for="{{locationList}}" wx:key=""> <view class="search-result" bindtap="onTap" data-key="{{item.address}}">{{item.name}} <view class="search-result-desc">{{item.address}}</view> </view> </block></scroll-view></view><view class="getLocation"bindtap="getLocation">点击定位当前位置</view><view class="addLocation">新增收货地址 <view class="addLocation-icon">+</view></view><view class="myLocation">我的收货地址</view><view class="LocatonInfo"></view><view class="userTel"></view>这个界面主要涉及到的就是弹出层和百度地图API的调用,调用方法可以查看百度地图API,具体点击事件代码如下:
getLocation: function () { wx.getLocation({ type: 'gcj02', success: function (res) { var latitude = res.latitude var longitude = res.longitude wx.request({ url: 'http://api. ** p.baidu.com/geocoder/v2/?ak=btsVVWf0TM1zUBEbzFz6QqWF&coordtype=gcj02ll&location=' + latitude + ',' + longitude + '&output=json&pois=0', method: "get", success: function (res) { console.log(res.data.result.for ** tted_address) wx.setStorageSync('location', res.data.result.for ** tted_address.substr(res.data.result.for ** tted_address.indexOf('市') + 1, 10)) } }) } }) wx.switchTab({ url: '/pages/home/home' }) },input: function (e){ if(e.detail.value){ this.setData({ hidden: false }) this.search(e.detail.value); }else{ this.setData({ hidden: true }) } },search: function (text){ var that = this; wx.request({ url: 'http://api. ** p.baidu.com/place/v2/search?query=' + text +'&page_size=20&page_num=0&scope=2®ion=南昌&output=json&ak=btsVVWf0TM1zUBEbzFz6QqWF', success: function(res){ console.log(res); that.setData({ locationList:res.data.results }) } }) },点菜界面效果图如下:
页面结构如下:
<import src = "../common/orderPage.wxml"/><import src = "../common/commentPage.wxml"/><view class="container" disable-scroll="true"> <view class="header"> <block wx:for="{{swiperTitle}}" wx:key=""> <view class="title {{index==currentPage?'selected':''}}" data-index="{{index}}" bindtap="turnPage">{{item.text}}</view> </block> </view> <swiper class="swiper" current="{{currentPage}} bindchange="turnTitle"> <swiper-item id="orderPage"> <template is="orderPage" data="{{menu,selected,howMuch,cost,pullBar}}"/> </swiper-item> <swiper-item id="commentPage"> <template is="commentPage" data="{{categoryList}}"/> </swiper-item> <swiper-item id="restaurantPage"></swiper-item> </swiper></view>菜单页面如下:
<template name="orderPage"> <scroll-view class="orderPage-sideBar" bindscrolltolower="lower" scroll-y="true"> <block wx:for="{{menu}}" wx:key=""> <view class="menuList"> <view class="menu {{index==selected?'selected':''}}" data-index="{{index}}" catchtap="turnMenu">{{item.typeName}}</view> </view> </block> </scroll-view> <scroll-view class="foodList" scroll-y="true"> <view class="title">{{menu[selected].typeName}}</view> <block wx:for="{{menu[selected].menuContent}}" wx:key=""> <view class="food"> <i ** ge class="img" src="{{item.src}}"></i ** ge> <view class="food-info"> <view class="name">{{item.name}}</view> <view class="sales">月售 {{item.sales}} 赞 {{item.rating}} </view> <view class="price">¥ {{item.price}}</view> </view> <view class="food-numb"> <view class="remove" bindtap="removeFromTrolley" hidden="{{item.numb==0}}" data-index="{{index}}">-</view> <text class="text" hidden="{{item.numb==0}}">{{item.numb}}</text> <view class="add" bindtap="addToTrolley" data-index="{{index}}">+</view> </view> </view> </block> </scroll-view> <view class="footer {{cost!=0?'active':''}}"> <view class="howMuch"> <view class="img" style="background:{{cost!=0?'#FFD161':'#E7E7E7'}};"> <i ** ge src="/pages/i ** ges/trolley.png" style="width:60rpx;height:60rpx;"></i ** ge> </view> <view class="cost" hidden="{{cost==0}}">¥{{cost}}</view> <view class="free">免配送费</view> </view> <view class="pay">{{cost!=0?'去结算':'15元起送'}}</view> </view></template>tab切换这个界面最主要的功能就是tab切换,和点菜功能。其中tab切换其实用的还是swiper,因为swiper有一个current属性表示的是swiper当下显示的页面的序号,只需要将tab中被激活的项与swiper的页面互相绑定就可以了,具体代码如下:
turnPage: function (e) { this.setData({ currentPage: e.currentTarget.dataset.index }) }, turnTitle: function (e) { if(e.detail.source=="touch"){//判断是否是滑动引起的界面切换 this.setData({ currentPage: e.detail.current }) } },当点击title中的项时获取当前序号,再将它赋值给current,当手指滑动swiper时触发bindchange事件,获取当前页面序号,使相应序号的title处于被选中的状态。有一个值得注意的地方是当点击title中的项时也会触发swiper的bindchange事件,但是我们只想让它在滑动swiper时触发,否则就会出现setData过于频繁的警告,所以我们需要在turnTitle中加一段判断语句,判断页面滑动的原因是否为滑动,如果不是则不执行下面的语句。 点菜功能只是数据绑定界面的更加复杂的应用,而且还有许多不妥之处,这里就不作说明了,有兴趣的朋友可以去我的GitHub看详细的代码。
总结这次项目是本人的第一个微信小程序项目,希望能给大家提供一些参考价值,有什么问题和想说的都可以在评论区告诉我,文章和代码中诸多不妥当的地方也劳烦各位不吝言辞,多多斧正。这样才能帮助我更快的进步,感谢!
项目地址:https://github.com/tzc123/wx_project_meituan
作者:zjc348链接:zjc348/wx_project_meituan: 美团小程序著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。Copyright © All rights reserved | Colorlib 沪ICP备2021024381号-16
扫码咨询与免费使用
申请免费使用