项目快作完了,作下总结:html
需求:登陆模块、设备列表展现模块、我的中心模块、详情模块,总共分为这四个模块内容。git
1、拿到项目需求后,先建立了一下项目,而后封装了一些经常使用的方法,http请求和时间处理函数Dategithub
一、封装http请求,比较简单用Promise 进行封装,把返回的数据resolve(res),而后把http.js引入到全局app.js中,利用globalData{}对象进行全局管理。web
const baseUrl = 'https://xxx'
let http= (method, urlData)=>{ return new Promise((resolve,reject)=>{ wx.request({ url: baseUrl + urlData.url, data: urlData.data, method: method, header: { "Content-Type": "application/json", "Authorization": "bearer " + wx.getStorageSync('token') }, success: function (res) { resolve(res) }, fail: function (err) { reject(err) } }) }) } export default http
二、由于项目中须要对时间进行处理,后台返回的是时间戳这里就封装了一个时间转换处理函数,代码比较简单,同http同样引入全局。npm
2、想了想为了加快开发速度,就在项目中引入vant ui 框架,使用简单npm 下载下来,在开发工具中构建一下npm就ok了,使用方法官方已给出:https://vant-contrib.gitee.io/vant-weapp/#/introjson
3、登陆模块开发小程序
需求:一键登陆、输入帐号密码登陆,两种方式后端
一、一键登陆api
分析:数组
(1)、一键登陆的帐号主要来源是微信绑定的手机号码,因此咱们要进行手机号码受权(拿到encryptedData和iv,后端解码获取到手机号码)
(2)、在登陆时咱们须要获取code登陆标识(有时间限制,只能使用一次)
(3)、发送登陆请求,把code、encryptedData、iv提交给后端作登陆处理,返回sessionkey和token并保存
二、帐号密码登陆
分析:
(1)、发送请求向后端提交帐号和密码,返回token并保存
(2)、这里输入帐号和密码是要作双向绑定,监听输入事件把输入内容赋值给user和password
(3)、在作清空和密码隐藏显示时图标不要放在输入框内,否则会触发冒泡,键盘不会收回
(4)、注意在隐藏和显示密码这儿,必定好看清文档,是password属性的true和false来控制隐藏于显示,不是type属性
这块内容没啥难点,不放代码了!
4、首页&列表页面
一、初始化页面
分析:
(1)、在页面加载前要判断是否已登陆(根据保存的token和sessionkey)
(2)、已登陆下,区分是一键登陆仍是帐号密码登陆(帐号密码登陆无sessionkey),而后直接请求列表数据,请求根据状态码若是token过时,走刷新token的接口(刷新成功则保存刷新后的token从新进入该页面,不然提示从新登陆 ==> 清空缓存 ==> 跳转到登陆页)
二、页面布局
九宫格布局----父盒子
wx.previewImage({
urls: urlList //urlList是数组
})
二、退出登陆要清空缓存
6、详情页面
需求:展现设备详情数据,设备差很少100种左右,每一个设备的ui不一样;重点来了,不一样设备详情页面能够左右滑动到下一个页面(顺序为首页的顺序,滑动效果轮播图那样)
天哪这一个页面得写多少代码啊啊啊...,后台接口只有获取设备列表和根据设备id获取详情数据,且格式因为是转发不能修改
额,只能一点点写了,
一、直接把官方的swiper组件拿过来开撸,为了减小请求直接把首页请求的设备列表list传到的详情页并保存
二、初始化,根据传递的设备id,请求详情数据,把须要的数据绑定到list数组下对应的设备数据对象中
三、dom结构是根据不一样设备ui进行了划分,共有的和私有的,经过wx-if来进行要渲染的内容
四、要区分当前详情数据第几页,这里首先把拿到的list数组过滤,获得有详情页的数据列表(有些设备无详情页),而后循环查找当前的设备id,循环的key+1值就是第几个设备,而且把当swiper组件的当前页页设置为key。
五、左右滑动的时候,根据滑动后触发事件,得到的索引做为list的索引,拿到下个设备的id,而后进行渲染(渲染前清除上个设备的dom)
六、这里且套了屡次循环,主要仍是请求到的数据格式不理想,致使了写了不少处理格式的代码
七、测试,发现bug,左右来回滑动很快的时候,停下来后页面会不停抖动,查了下是组件的bug。
解决方式:对滑动事件触发后 的触发源作判断,若是是touch则进行页面渲染,解决了抖动问题;
测试发现出现没法滑动的bug,分析是滑动后更改当前页致使
解决方式:作节流,当触发滑动事件后到渲染数据这段时间禁止页面滑动,当渲染完成才容许滑动,如今就是如何禁止页面滑动,组件没这个属性,想到经过添加一个透明层来阻止滑动执行(有更好的方法的小伙伴能够分享下)。
七、须要增长要实时更新数据和上报推送消息-------webSocket
上网找了下有不少现成的轮子,看了下很简单。
附上原文地址:http://www.javashuo.com/article/p-pgwczior-nx.html
var sotk = null; var socketOpen = false; var wsbasePath = "ws://开发者服务器 wss 接口地址/"; //开始webSocket webSocketStart(e){ sotk = wx.connectSocket({ url: wsbasePath, header: { 'content-type': 'application/x-www-form-urlencoded' }, method: "POST", success: res => { console.log('小程序链接成功:', res); }, fail: err => { console.log('出现错误啦!!' + err); wx.showToast({ title: '网络异常!', }) } }) this.webSokcketMethods(); }, //监听指令 webSokcketMethods(e){ let that = this; sotk.onOpen(res => { socketOpen = true; console.log('监听 WebSocket 链接打开事件。', res); }) sotk.onClose(onClose => { console.log('监听 WebSocket 链接关闭事件。', onClose) socketOpen = false; }) sotk.onError(onError => { console.log('监听 WebSocket 错误。错误信息', onError) socketOpen = false }) sotk.onMessage(onMessage => { var data = JSON.parse(onMessage.data); console.log('监听WebSocket接受到服务器的消息事件。服务器返回的消息',data); }) }, //发送消息 sendSocketMessage(msg) { let that = this; if (socketOpen){ console.log('经过 WebSocket 链接发送数据', JSON.stringify(msg)) sotk.send({ data: JSON.stringify(msg) }, function (res) { console.log('已发送', res) }) } }, //关闭链接 closeWebsocket(str){ if (socketOpen) { sotk.close( { code: "1000", reason: str, success: function () { console.log("成功关闭websocket链接"); } } ) } }
八、需求更改 要用MQTT
好吧,开撸
分析须要:在详情页面只刷新页面数据不作消息提示,其余页面作弹框推送提示
下载mqtt.js 地址:https://unpkg.com/mqtt@4.1.0/dist/mqtt.min.js
代码mqtt全局链接,若是没有页面都要链接一次的话会出现bug ,webSocket链接有次数限制,官方说明:https://developers.weixin.qq.com/miniprogram/dev/api/network/websocket/wx.connectSocket.html
这里由于要在登陆以后链接mqtt,而且主题是动态根据用户id而改变的,因此这里封装了个Promise,并把链接后的client导出,作数据监听。
var mqtt = require('utils/mqtt.min.js'); var client = null; var connect = function(id) { return new Promise((resolve,reject)=>{ const options = { connectTimeout: 4000, // 超时时间 clientId: 'wx_' + parseInt(Math.random() * 100 + 800, 10), port:8084 } client = mqtt.connect('wxs://xxx', options) client.on('reconnect', (error) => { console.log('正在重连:', error) }) client.on('error', (error) => { console.log('链接失败:', error) }) let that = this; client.on('connect', (e) => { console.log('成功链接服务器') //订阅主题 client.subscribe(['主题1'+id, '主题2'+id], { qos: 1 }, function (err) { if (!err) { console.log("订阅成功") resolve(client) } }) }) }) }
监听:
client.on('message', function (topic, message, packet) { console.log(packet) })
注意它来了!
connect(id)只在首页调用一次,而且把返回的client存为全局使用,而后就能够在详情页面中经过全局client直接监听messgae并作响应的逻辑了。
关闭链接:在退出登陆或者判断token不存在的时候执行,因为关闭后它会可能自动链接,因此最好是在判断token不存在时关闭链接
wx.closeSocket()
附官方文档:https://github.com/mqttjs/MQTT.js
结束啦!
总体就这些内容,具体的不一样设备ui的问题涉及的一些知识点,之后有时间在补存或另写一章。