前言

写在项目前的话:

临近期末了,各学科纷纷结课,随之而来的是各个课设的纷至沓来。俗话说得好,大学生的生活前五个月是温水泡脚,那么最后一个月的就是将前五个月泡脚的水喝下去。作为一个平日里摸鱼摸惯的摸鱼王,课设是最为头疼却又逃不掉的一环。这次的课设,是要模仿一个微信小程序,按照功能的完成度和难度来打分。作为摸鱼王的我,自然而然想起了“看起来简单”又界面好看(主要是靠图片撑起来的颜值)且天天都在用的————古茗点单小程序。而在实现的过程中,我才发现原来看起来简单的古茗小程序实际上细节满满。让我这个摸鱼王叫苦连天。

效果展示(模仿的是上个版本的古茗小程序,因为在模仿小程序中古茗更新过一次

首页页面

点单页面

选购页面

订单页面

我的页面

以上就是我们模仿的古茗小程序的主要功能。

一、开始前所需要的准备

  • 申请账号:小程序注册,填写信息和提交相应的资料,就可以拥有自己的小程序帐号。

  • 开发工具:微信开发工具

  • 数据来源:

    古茗各种图片来源:Fiddler抓包工具下载

    如何使用Fiddler抓取图片教程:Fiddler教程

  • icon:iconfont阿里巴巴矢量图标库

  • 部分组件的引用:Vant Weapp

二、初始化一个小程序

  1. 新建一个文件夹
  2. 打开小程序,新建一个小程序
  3. 目录结构,如下所示
WEAPP
| -cloudfunctions
| -miniprogram
|     - assets // 静态变量
|         -GIF  //抓取的GIF
|         -icons //源于iconfont的icon图标
|         -images//抓取的静态图片
|     - componnents //组件
|         - panel // 购物车组件
|     - database //数据库
|         - db.js //存放所有数据的地方
|     - pages //各个页面
|         -home //主页
|           -home.js//js文件
|           -home.wxss//css样式文件
|     - utils //全局函数
|     - app.js              // 系统的方法处理文件
|     -app.json             // 系统全局配置文件
|     -app.wxss             // 全局的样式表
|     -config.json      // 域名等配置文件
| -README
复制代码
  1. 小程序app.json文件配置
  "pages": ["pages/home/home",//主页"pages/jump/jump",//shopping假跳转页面"pages/shopping/shopping",//显示各个店面信息页面"pages/order/order",//点单页面"pages/my/my",//我的页面"pages/teaList/teaList",//奶茶点单页面"pages/orderDetail/index"//点单详情页面],"permission": {"scope.userLocation": {"desc": "你的位置信息将用于小程序点单定位"}},    //请求访问用户地理位置(小程序使用位置所必要的)//窗口"window": {"backgroundColor": "#F6F6F6",//窗口背景色"backgroundTextStyle": "dark",// 下拉背景字体、loading 图的样式,仅支持 dark/light"navigationBarBackgroundColor": "#fff",// 顶部tab背景颜色"navigationBarTitleText": "古茗",//顶部显示标题"navigationBarTextStyle": "black"// 导航栏标题颜色,仅支持 black/white},//tab导航条"tabBar": {"selectedColor": "#000000", //选中时样式"borderStyle": "black", // tabbar上边框的颜色, 仅支持 black/white"backgroundColor": "#fff",//背景颜色/** * tab列表,最少2个,最多5个 * text: 对应文案* pagePath: 对应页面路由* iconpath: 图标对应路径* selectIconPath: 选中时的图标对应位置 **/"list": [{"text": "首页","pagePath": "pages/home/home","iconPath": "assets/icons/home.png","selectedIconPath": "assets/icons/home-active.png"},{"text": "点单","pagePath": "pages/jump/jump","iconPath": "assets/icons/shopping.png","selectedIconPath": "assets/icons/shopping-active.png"},{"text": "订单","pagePath": "pages/order/order","iconPath": "assets/icons/order.png","selectedIconPath": "assets/icons/order-active.png"},{"text": "我的","pagePath": "pages/my/my","iconPath": "assets/icons/my.png","selectedIconPath": "assets/icons/my-active.png"}]},//全局调用的Vant组件"usingComponents": {"van-search": "./miniprogram_npm/@vant/weapp/search/index","van-cell": "./miniprogram_npm/@vant/weapp/cell/index"},//默认样式"sitemapLocation": "sitemap.json","style": "v2"
}
复制代码

5.创建两个数据表

注意:一定要创建名字一样的数据表哦

这些弄完就可以开始做一个古茗点单小程序啦!

三、开发时所遇到的问题以及解决方案

1. swiper 组件

在古茗小程序中,很多地方都用到了swiper组件,我们通过查阅文档,也都实现了古茗小程序所展示的效果 以下是一些我学习完后的心得

心得:

  1. swiper是滑块视图容器。其中只可放置组件,否则会导致未定义的行为。
  2. autoplay 类型是boolean 默认值是false 非必填 作用为:是否自动切换 我们将它的值改为true,它就会自动播放了
  3. circular 类型是boolean 默认值是false 非必填 作用为:是否采用衔接滑动
  4. 其中的swiper-item 都用占位符绑定了图片的位置和图片id

2.假页面跳转

在开发中,我们发现古茗的shopping页面(即点单页面),当我们点击后,下面并没有出现导航栏,经过查询资料发现,小程序并没有提供让导航栏暂时消失的的方法,在我们摸不着头脑时。我们发现当点击点单页面时,出现页面跳转的效果。因此我们推断,这个选店的页面,可能只是普通的页面并非导航栏页面。(小程序中导航栏页面与普通页面有很多不一样的地方)

解决方案:

只要在导航栏页面中的onShow方法中,添加跳转页面的方法,让导航栏页面加载完后(但实际什么也没有写),自动跳转我们渲染好的页面即可(即真正的点单页面)。解决代码如下:

onShow: function () {wx.navigateTo({url: '/pages/shopping/shopping',})},
复制代码

但随着假页面(跳转页面)的出现,同时也有很多问题浮出了水面。例如wx.navigateBack(跳回上一个或多级页面)方法失效问题。

当点击这个按钮时,要返回上一个页面 即使用wx.navigateBack 返回到上一页面或多级页面。无论设置返回上级多少个页面,他会一直会在此页面不动。

出现问题的原因:

因为我们设置了一个假页面,选择店面的页面上一级是我们设置的假页面,假页面中的onShow方法。当加载完后又会跳到选择门店页面,所以在此时wx.navigateBack就已经完全失效了。

三、wx.navigateBack失效问题

由第二点我们知道,在这种情况下wx.navigateBack已经完全失去他的作用。但在古茗小程序中,这个跳转又是不可缺少的,因为一旦缺少,就会出现严重的页面跳转的BUG。因此我们不得不想出新的解决方案。

解决方案:

经过讨论,我们选择重新写一个方法来实现wx.navigateBack既定的功能。我们发现,如果从主页点击点单页面,再返回,那么就是返回到主页。如果从订单页面点击到点单页面,那么就是返回到订单页面。如果从我的页面点击到点单页面,那么就是返回到我的页面。因此,我们认为在这三个(主页,订单页面,我的页面)onShow方法中,将它们的跳转地址交给Storage(储存器储存起来)。到需要用时再取出来: 解决代码如下:

将地址存进去

onShow: function () {wx.setStorageSync('address', "/pages/home/home");},//此为主页,其他三个页面依此类推
复制代码

选择店面的页面中取出来

backLastPage() {let address = wx.getStorageSync('address')wx.switchTab({url: address,})},
复制代码

此时,wx.navigateBack失效的问题就完全解决了

你看,问题一个一个的来,一个一个解决不就行了。此时的我直接杀神附体,感觉什么问题都能KO

四、自定义顶栏的样式

我们发现,我们在app.json中这样设置,是全局性质的。但我们在选择店面的页面中,它的顶栏和全局的顶栏是不一样的

因此,我们需要diy选择店面的页面顶栏。我们只需要在需要diy的页面中的json的文件中添加"navigationStyle": "custom"就可以自己用wxss写出一个顶栏了

五、小程序中map组件的运用

腾讯位置服务推出《微信小程序解决方案》,从检索API、基础地图组件、个性化、插件、行业方案等多个层面,为不同场景需求的小程序开发者提供完整的地图能力。 个性化地图在小程序中,是已经给出了map组件的,因此运用起来是非常方便的。 以下,是我们设计的古茗小程序的map组件运用的一些总结:

  1. longitude 类型为number 无默认值 是必填的 作用是提供中心经度
  2. latitude 类型为number 无默认值 是必填的 作用是提供中心纬度
  3. scale 类型为number 默认值为16 不是必填 作用是用鼠标滑轮控制缩放级别,取值范围为3-20
  4. show-location 类型为boolean 默认值为false 不是必填的 作用是显示带有方向的当前定位点
  5. markers 类型为Array.marker 无默认值 不是必填的 标记点用于在地图上显示标记的位置(即奶茶店的位置)

而markers也是值得研究的

markers:

  1. id |类型为number 无默认值 不是必填的 marker点击事件回调会返回此id
  2. latitude | 类型为number 无默认值 是必填的 浮点数,范围 -90 ~ 90
  3. longitude | 类型是number 无默认值 是必填的 浮点数,范围 -180 ~ 180
  4. iconPath |类型是string 无默认值 是必填的 支持网络、本地、代码包路径
  5. width |类型是number/string 无默认值 不是必填的 默认为图片实际宽度
  6. height | 类型是number/string 无默认值 不是必填的 默认为图片实际高度

在我们模仿的古茗小程序中,由于没有店面的实体数据,没办法完全模拟古茗小程序,但为了增加使用者的体验感,我们写了个方法————获取到使用者当前的位置。并以使用者为原点,建立平面坐标系。生成了六个店面(位置随机),但店面的名字都是死数据。最大可能的模仿了古茗小程序的地图功能,实现代码如下:

onLoad: function () {var that = this;wx.getLocation({type: 'gcj02',success: (res) => {var latitude = res.latitudevar longitude = res.longitudethat.setData({latitude: latitude,longitude: longitude,})      }})//获取自身位置
复制代码

虽然这些都没有学过,但还是通过我查阅资料,没想到最终还是被我给解决了,此时浓浓的成就感就油然而生了

六、选择店面时,出现黄色边框以及确认店面提示框。

通过之前的效果展示,我们可以看见在选择店面的页面,我们选择不同的店面时,那店面信息四边会出现黄色的边框来表现已经选中,同时会出现对话框来确定这家店的信息。

要实现这个效果,我们首先得在写wxml时,在可点击的店面(view)中分别绑定data-index,在最外层bindtap绑定的方法中获取所点击的view的index值,再将index的值赋给我们所设的变量activeNavIndex

然后在wxml中用一个三元运算符进行判断

最后在wxss中写出默认时的样式和点击后的样式

这里有两个值得注意的点:

  1. activeNavIndex(我们所设置的变量)默认值应该为0,这样当我们不点击时就会默认第一家店出现黄色边框,这样符合我们的设计要求。如果以后需求不同(如都是默认样式又或者是最火爆的店面先出现黄色边框),也可以根据自己的需求设置
  2. 默认样式中,也要设置边框(这里运用的是border),宽度要和点击后的宽度一致,达到控制变量的效果。但默认的时候,可以将边框设置成白色或者添加透明度,让其“消失”。如果不加默认样式时的边框,那么点击后全局的样式就会改变,非常的别扭。

然后就是点击后出现的对话框了,小程序中给了一个wx.showModal方法

在小程序中,非常方便的写出了对话框,这也是小程序的优点之一,开发非常的方便。

七、选商品页面菜单的开发

其实一开始要我解决这个问题,我是拒绝的,我毕竟可是摸鱼王,这么难的问题怎么可能交给我?我当时本来就想偷偷的划水。但想起我之前碰见的问题都解决的那么漂亮总不能在这半途而废吧。于是我又开始翻翻翻....

后来我发现,这个菜单还是有迹可循的,其中左边菜单栏的开发类似于第六点,也是添加点击事件,然后埋下index...... 不过值得一提的是,这里由于我wxml设计的一些原因。用border-left达不到我们所想要的效果,于是我们运用了另一个方法来添加点击后的样式。那就是————做了一个伪类,也算是这类问题的另一种解决方案了吧,如果以后碰见需要点击后的样式更花哨,更复杂的需求的话。伪类应该可以给你一个更大的发挥空间。

然后右边的商品栏才是这个问题的难点了。在解决这个问题前,我们得先来学习一下小程序中的scroll。

scroll总结:

  1. scroll-y 类型为boolean 默认值为false 不是必填的 作用是允许纵向滚动
  2. scroll-with-animation 类型为boolean 默认值为false 不是必填的 作用是在设置滚动条位置时使用动画过渡
  3. enable-back-to-top 类型为boolean 默认值为false 不是必填的 作用是iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向
  4. scroll-into-view 类型是string 无默认值 不是必填的 作用是值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素
  5. scroll-top 类型是number/string 无默认值 不是必填的 作用是设置竖向滚动条位置
  6. bindscroll 类型是eventhandle 无默认值 不是必填的 作用是滚动时触发,event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY}

知道这些基础知识后,我们来走进这个难点。

首先,数据的设计就十分讲究

 {title:'当季新品',products:[{title:'生椰拿铁冰激淋',tag:'新品',desc:'珍珠、冰激淋、生椰乳、咖啡液、牛奶生...',price:'16',pic:'https://img.gumingnc.com/newton/20210719053749CST84721626687469148.png?x-oss-process=image/resize,w_204,m_lfit '},{title:'龙井奶芙',tag:'新品',desc:'龙井、鲜奶乳、奶芙顶、坚果碎色清味...',price:'16',pic:'https://img.gumingnc.com/newton/20210719041227CST36011626682347798.png?x-oss-process=image/resize,w_204,m_lfit'},{title:'泡鲁达',tag:'新品',desc:'西米、多肉、红宝石、椰香白糯米、桂花...',price:'17',pic:'https://img.gumingnc.com/newton/20210609082139CST16401623241299533.png?x-oss-process=image/resize,w_204,m_lfit'}]}
复制代码

这是其中一个分类的所有数据。该项目有十一个这样的类

其次是wxml的布局,也很讲究,其布局大概是这样的

了解了结果,然后开始完成其功能了。 首先,因为scroll-into-view接收的是一个id,所以我们给每一个大类埋下一个index,加一个id='position{{index}}',然后我们在左边导航栏的中的点击事件添加一个setData。因为在左边我们也埋下了一个index,所以两边的index是一一对应的。所以有

this.setData({ idx: e, toView: 'position' + e })
复制代码

此时,我们再加上scroll-with-animation,将其的值设为true。此时,我们点击左边的导航栏时,右边就将商品对应上了。 然后,我们在onLoad函数中,将所有的类名带position的view筛选出来(注:一个大类的类名class='scroll-box position')

 wx.createSelectorQuery().selectAll('.position').boundingClientRect(function (rects) {that.setData({ positions:rects })}).exec();
复制代码

这里的rects返回的是一个数组,其中包含所有类名带position的节点信息,返回的节点信息中,每个节点的位置用leftrighttopbottomwidthheight字段描述。如果提供了callback回调函数,在执行selectQuery的exec方法后,节点信息会在callback中返回。这样,每个大类的信息就被储存起来了。

最后,就是写bindscroll函数了,

如果这个大类距离顶部小于等于滚动条加swiper宽度的话,我们就把她加进arr这个空数组, 最后拿到可视范围的大类之前埋入的index。返回给左边导航栏的idx,这样相对应的左边导航栏就会出现选中样式。如此,一个成功的菜单就完成了!

八、用户的等级制度以及满十赠一活动

这个可以说是比较简单的一个方法了,但却极大的增加了用户的交互。看起来高大上实际却又十分简单。 首先,从用户表中,拿出历史总杯数。也拿出此时用户的VIP等级。

以上,就是这个项目我们所解决的问题了

注意:

此处,由于数组的特性以及没有VIP等级大于等于0,等级和经验条一一对应。即达到一级需要六杯,二级需要十二杯,三级需要18杯,四级需要30杯......如果达到了经验条则等级加一。如果没达到,返回当前等级。

四、总结

本次开发,学到了很多小程序有关的知识。想起一路上碰到的困难,此刻终于也能画上一个圆满的句号。相比起知识储备,解决问题的方法和思维才是更为重要的东西。一路上磕磕碰碰,也算是干了这五个月的洗脚水吧。在开发过程中,我也深刻的感觉到,微信小程序确实对新人很友好,很多方法小程序都给了现成的。非常的方便(手动点赞),小程序真的很适合新人学习前端。可以当作前端的敲门砖哦,毕竟这么菜的我,也能写出这样的小程序(不是自卖自夸)。小程序是真的是你下一点功夫,就能立竿见影的一门学问了。

另外,此次项目中仍有许多功能不够完善,一些细节还可以继续优化,路漫漫其修远兮。希望大家能给出宝贵的意见,如果文章中有错误和不足欢迎批评指正。也欢迎和我在评论区讨论各种有关小程序的问题哦~

如果你觉得这篇文章让你学习到了知识的话,麻烦给个免费的赞呗~,这对创作者真的很重要T.T

另外另外,项目地址也想要个免费的star(づ。◕‿‿◕。)づ★

只要功夫深,菜鸟也能写出细节满满的古茗点单小程序相关推荐

  1. 让VB菜鸟最快写出自己的外挂

    让VB菜鸟最快写出自己的外挂.通杀所有游戏 这年头,在这个论坛里面已经没有什么技术贴了...呵呵~发一篇惊天地,泣鬼神的帖子.当然这个只是模拟键盘的终极模拟.呵呵~   键盘是我们使用计算机的一个很重 ...

  2. 按钮 小程序 弹出菜单_公众号怎么关联小程序

    小程序开发之后很多人不知道怎么推广,今天给大家聊一下常见的在公众号里面关联小程序,直接打开我们单位小程序页面. 小程序正式推出后不久,微信就推出"公众号关联小程序"的功能.公众号运 ...

  3. 优秀的java代码_像这样写,Java菜鸟也能写出牛逼的代码

    场景一 有时候我们会遇到一个方法就是占满了整个屏幕,其中各种if else 判断 ,for 循环嵌套,时不时来穿插着各种a b c参数,让人看得实在是眼花缭乱.让后面维护的人望而却步,也实在的代码块后 ...

  4. 三周写出高性能的Python代码,这些小技巧你值得一试。

    1一个不上进的 Python 使用者 我是一个有 C 语言背景的开发者.最近转做了 Python,平时用 Python 还算 6,这周在给新员工分享工作之后,有个小孩跑来问我:"哥,你是学 ...

  5. 自己写的一个抢票加速的Python小程序源码分享-----纯属娱乐

    最近这段时间频频看到微信群里发什么 抢票加速,智行.携程.飞猪.美团,对于我这能坐客车就不坐火车的人来说,无所谓靠谱不靠谱 突发奇想的整理了下整个抢票加速的逻辑,写了这个小程序,代码很low,拒绝批评 ...

  6. python抢票软件源代码_自己写的一个抢票加速的Python小程序源码分享-----纯属娱乐...

    最近这段时间频频看到微信群里发什么 抢票加速,智行.携程.飞猪.美团,对于我这能坐客车就不坐火车的人来说,无所谓靠谱不靠谱 突发奇想的整理了下整个抢票加速的逻辑,写了这个小程序,代码很low,拒绝批评 ...

  7. 给我写个10000字的微信预约座位小程序论文

    我非常乐意为你写一篇关于微信预约座位小程序的10000字论文.本文旨在通过深入分析来解释微信预约座位小程序的运作原理,及其对日常生活的重大影响. 首先,我们将回顾一下微信预约座位小程序的发展历史,并着 ...

  8. unity 输入框弹出输入法_输入法也开始做小程序!对其他平台直接降维打击?

    今年,各种想得到的想不到的流量巨头都相继入局,小程序生态的一场混战在所难免. 作者丨Tsai 2019年,堪称小程序元年,一个个流量巨头高举火把逐渐"照亮"小程序这片暗夜. QQ& ...

  9. 王者荣耀出装与铭文推荐助手微信小程序源码支持多种流量主

    这是一款王者荣耀助手的一款小程序源码 该小程序主要功能就是提供各个英雄出装和铭文查询 功能虽然单调但是对于玩王者的朋友来说还是挺实用的! 目前该小程序源码已支持多种流量主模式 小程序源码下载地址: C ...

最新文章

  1. 微信小程序开发-滑动操作
  2. JTable动态显示隐藏列
  3. Asp.net使用代码修改配置文件的节点值
  4. 如何将URL转换成对象
  5. 设置dns_网络速度缓慢怎么办?轻松一键修改DNS设置让网速提升五倍
  6. horizon client 无法识别域_iText for Mac(OCR识别图中文字工具)
  7. 02-mysql数据库的特点-卸载-安装-配置-mysql5.5版本
  8. [转载] python字符串情感分析_python进行情感分析
  9. 利用子查询解决复杂sql问题
  10. 依赖注入及AOP简述(四)——“好莱坞原则”和依赖注入框架简介 .
  11. tuxedo 中间件命令
  12. ubuntu下使用vscode编译调试yolov3
  13. SparkStreaming + LogisticRegression 实现路况预测
  14. npoi word生成HTML,C# 使用NPOI生成Word文档(按照模板)
  15. ULINE(插入水平线)
  16. 对复利计算器和股票投资的总结
  17. CIS基准测试工具kube-bench使用
  18. 导出icloud照片到电脑_如何将Apple iCloud和iPhone联系人导出到Windows 10
  19. MATLAB求函数极限的简单介绍
  20. keras中的卷积层池化层

热门文章

  1. JavaScript【趣味】做一个网页版2048
  2. python卡路里程序_SpiderFlow平台v0.3.0初次使用并爬取薄荷网的热量和减法功效
  3. 10天学会flutter DAY7 flutter 玩转基础Widget
  4. 《那些年啊,那些事——一个程序员的奋斗史》——52
  5. 【算法】_013_矩阵乘法
  6. matlab雷达对抗,基于MatLab的有源压制性干扰信号模拟与实现.pdf
  7. IntelliJ IDEA生产力工具 -- 源码注释翻译神器
  8. 易云维促进智能医院发展,建设医院智慧后勤综管平台具有重大意义
  9. 世界十大顶级家族家训
  10. 无线WiFi覆盖工程问题解决_如何解决同频干扰