关于小程序
之前没有用过小程序,只知道是腾讯自己实现的一套标准,也没有想过研究,这几天有个朋友想做一个小程序点菜的菜单系统,于是乎,就抱着试一试的心理看了一下小程序的【官方文档】。
使用小程序需要使用微信自己的开发工具,然而,这个工具非常多的BUG,针对教程中的断码片段实验,有很大几率不能运行,而且必须需要扫码登录,这个地方让我实在是恶心到了。至于其他的一些恶心之处,下面是举例说明:
当我登录时
当我找回密码时
当我注册时
这真是让人喵喵喵了,说实话,我是很讨厌微信的风格,微信是一个封闭到骨子里的生态圈,从微信的内置浏览器到公众号里的文章,无不散发着打造互联网小花园的野心,然而,做出的很多东西像一坨*,但是由于其庞大的用户量,你又不能不吃。
注册公众号
好吧,我忍了对我的各种摧残,因为上面的原因,我已经损失了4个可以注册的邮箱,因为忘记密码的原因永远也找不回来了。我只好拿出我第五个也是最后一个邮箱注册了一个账号,进入了小程序的申请流程。啪啪啪申请完后,下载了它的编程工具,喵喵喵,也要扫码登录,恶心!登进去了之后又是一堆框框让你填,如果是单机的话,那就呵呵了,关键是这货虽然能联网,但是你换一个电脑登录,你也别想找到你再上面提交的代码!好,不吐槽了,下面接着往下看。。
整体结构
对照着官方文档,首先要看的就是小程序到底是什么鬼,到底怎么开发,这个看简易教程就够了,实话实说,教程还是挺清晰的,为数不多的看得懂并且看得下去的教程,个人理解小程序就是一个前端框架,有点类似于VUE的那种,做了数据绑定和路由啊一些功能,后台方面集成了腾讯自己的一些接口,比如登录,地图,支付等等。如果是简单的展示页面,那么不用后台也是Ok的,但是如果是商城的网站,那么除了这个前端以外,必须还要对接一个后台商城系统的,通过https传输信息,https也是必须要在腾讯的后台中注册一下才能用。
代码结构
这个代码结构也是很有小程序的调性,那就是非常简单而且固定。结构就像这样:
以页面为单位,每隔页面下面都有四个标准的文件,分别为js,json,wxml,wxss。最外层缺少wxml文件,但是多了一个project.config.json。
- js是页面逻辑控制的文件,但是初始数据也都会往里面放。
- json我之前理解是放数据的,但是看了几个例子,都是放页面的一些配置的地方,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等这些。
- wxml类似于html,放一些元素的位置,里面是腾讯定义的各种标签
- wxss类似于css,放一些样式文件
- wxs不是默认生成的page中的文件,但是教程中也有提到,这是自动生成页面的脚本语言文件,官方称呼是模块,每一个 .wxs 文件和
标签都是一个单独的模块。这个文件里面有一个特殊的标签wxs,类似于包含有js的html。感觉这个鸡肋,应该和wxml合并在一起才对。 - project.config.json 这个不用看,应该是系统的配置文档
实际开发的体验
先吐槽,微信开发工具贼难用,删除都必须一个文件一个文件的删,而且page目录如果是第一次用,绝对非常懵逼,因为它会自动生成基本的四个page文件,但是出现的位置往往都不是你希望出现的位置。
由于小程序的特性,基本上都是以页面为单位,对于一个页面不多的程序,很多功能都不一定用的上,常用的几个功能如下,需要优先看:
- 页面的起点,路由方式
- 页面元素如何显示
- 页面如何调用各种方法
- 页面中元素的监听
- 页面与后台的数据对接
感觉如果需要做一个要求不太高的小程序,解决以上问题基本就可以开发了。官方文档比较细,针对每一个小点都介绍得比较细,但是作为一个面向github编程得程序员,直接网上copy一个项目进行代码阅读可是快多了。嗯,就是这样。
- 页面得起点是index/index,不知道它得加载逻辑是什么,只能怀疑是根目录下面得json文档中pages得第一条值,这个不是很重要,反正这个就是起点。当然,可以按照我图片得示例,文档结构可以改一下更清晰:
。当第一个页面做完以后,页面之间得超链接可以用navigateTo, redirectTo等方式进行。当然注意点,如果你设置了tarbar(再json中设置),就不能用navigateTo, redirectTo了,要用reLaunch方法,这些文档中都有,但是由于看得比较粗,导致这个地方调试了好久。 - 关于页面元素得显示问题,由于做的是页面双向绑定,那么修改page中得data,会自动改变data值再页面中的显示,如果修改呢,使用setData即可。
- 调用方法分为从页面中调用和从方法体中调用,方法体中调用其他的方法类似于js中的function调用,页面的中的调用常见的有滑动调用,点击调用等等,这个要结合文档看一下写法,和js差别不大。
- 页面中的监听,监听方法一般都在js文件中的page/on***中,里面有很多监听,比如页面的加载,页面的下拉刷新,这些如果用得到话,再到文档中查询。
- 前后端的对接是一个大头,最重要的一个API就是网络传输-->
wx.request
方法
wx.request({
url: 'test.php', //仅为示例,并非真实的接口地址
data: {
x: '' ,
y: ''
},
header: {
'content-type': 'application/json' // 默认值
},
success: function(res) {
console.log(res.data)
}
})
这种基于http的传输必然涉及到安全问题,微信采用https的传输形式可以使传输内容相对比较安全,但是作为后台还是要对接口的开放对象做一个控制,不能针对所有的域名都开放,需要再后端做一个域名访问的控制,只允许微信小程序端的域名访问。另外,可以再后台生成token,每次访问都要校验token值做一个判断。
一个经典的问题
如何实现一个饿了么点餐的菜单表
先看需求:
- 点击左边的栏目,调转到列表的相应位置
- 滚动右边的菜单,左边的菜单title会跟着变
实现思路:
- 左边,右边的文件都从网络中获取
- 左边点击一个栏目,改变该栏目的样式,获取该栏目的index(索引值),然后跳转到右侧的索引位置。
- 右边滑动的时候,需要监控滑动的距离,根据距离计算出当前是属于哪一个模块,并且修改左边模块的样式
- 实际操作的时候一个bug,点击左边的栏目时,由于第二步的操作会带来第三步骤的操作,会引发一个bug,导致左边的点击的栏目会往上跳一个,这里需要引入一个判断属性judge,当judge为0,代表点击左边的操作,这样,执行第三步时候先判断一个judge为false才执行具体操作,第三部结束前将judge改为1,就能解决这个bug。
js局部
var judge=1
Page({
/**
* 页面的初始数据
*/
data: {
listData: [],
activeIndex: 0,//需要改变样式的index
toView: 'a0',
scrollTop: 100,
screenWidth: 667,
showModalStatus: false,
currentType: 0,
currentIndex: 0,
...
}
...
/**
*点击左边菜单
*/
selectMenu: function (e) {
var index = e.currentTarget.dataset.index
console.log(index)
this.setData({
activeIndex: index,
toView: 'a' + index,
// scrollTop: 1186
})
judge=0;
console.log(this.data.toView);
},
/**
*滑动右边
*/
scroll: function (e) {
console.log(e);
console.log(this.data.scrollTop)
console.log(this.data.toView)
if(judge>0){
var dis = e.detail.scrollTop
if (/**判断dis的距离属于哪一个模块*/) {
this.setData({
activeIndex: /*该模块的index*/,
})
}
}
judge = 1;
},
wxml前端页面
<scroll-view scroll-y="true" style='height:1200rpx;' bindscroll="scroll" scroll-into-view="{{toView}}" scroll-top="{{scrollTop}}">
<view class="content" id="a{{index}}" wx:for="{{listData}}" wx:key="unique">
<view class='list-tab'>{{item.name}}</view>
<view class='content-list' wx:for="{{item.foods}}" wx:key="unique" wx:for-item="items" wx:for-index="indexs">
<view class='list-image-box'>
<image class="list-image" mode="widthFix" src='{{items.image_url}}'></image>
</view>
<view class='issue-name'>
<view>{{items.name}}</view>
<view style='margin-top:20rpx;color:#F05A86'>
¥ {{items.specfoods[0].price}}.00
<i class="iconfont icon-jiahao2fill plus-icon" data-type="{{index}}" data-index="{{indexs}}" bindtap="selectInfo"></i>
</view>
</view>
</view>
</view>
</scroll-view>
可以实现这个功能。
加购物车功能
这个功能也是一样,需要再page/data中加入一个数组,专门记录商品对象的相关信息,删除和增加都从数组里面增减,修改商品的属性即时更改对象的属性,当然如果加料的话,修改价格,最好是将料的价格和商品原价实际价格分开存放。
代码略