小程序项目总结

项目快做完了,做下总结:

 

需求:登录模块、设备列表展示模块、个人中心模块、详情模块,总共分为这四个模块内容。

一、拿到项目需求后,先创建了一下项目,然后封装了一些常用的方法,http请求和时间处理函数Date

1、封装http请求,比较简单用Promise 进行封装,把返回的数据resolve(res),然后把http.js引入到全局app.js中,利用globalData{}对象进行全局管理。

 

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": wx.getStorageSync('token') }, success: function (res) { resolve(res) }, fail: function (err) { reject(err) } }) }) } export default http

 

2、因为项目中需要对时间进行处理,后台返回的是时间戳这里就封装了一个时间转换处理函数,代码比较简单,同http一样引入全局。

 

二、想了想为了加快开发速度,就在项目中引入vant ui 框架,使用简单npm 下载下来,在开发工具中构建一下npm就ok了,使用方法官方已给出:https://vant-contrib.gitee.io/vant-weapp/#/intro

 

三、登录模块开发

需求:一键登录、输入账号密码登录,两种方式

1、一键登录

分析:

(1)、一键登录的账号主要来源是微信绑定的手机号码,所以我们要进行手机号码授权(拿到encryptedData和iv,后端解码获取到手机号码)

(2)、在登录时我们需要获取code登录标识(有时间限制,只能使用一次)

(3)、发送登录请求,把code、encryptedData、iv提交给后端做登录处理,返回sessionkey和token并保存

 

2、账号密码登录

分析:

(1)、发送请求向后端提交账号和密码,返回token并保存

(2)、这里输入账号和密码是要做双向绑定,监听输入事件把输入内容赋值给user和password

(3)、在做清空和密码隐藏显示时图标不要放在输入框内,不然会触发冒泡,键盘不会收回

(4)、注意在隐藏和显示密码这儿,一定好看清文档,是password属性的true和false来控制隐藏于显示,不是type属性

 

这块内容没啥难点,不放代码了!

 

四、首页&列表页面

1、初始化页面

分析:

(1)、在页面加载前要判断是否已登录(根据保存的token和sessionkey)

(2)、已登录下,区分是一键登录还是账号密码登录(账号密码登录无sessionkey),然后直接请求列表数据,请求根据状态码如果token过期,走刷新token的接口(刷新成功则保存刷新后的token重新进入该页面,否则提示重新登录  ==> 清空缓存 ==> 跳转到登录页)

 

2、页面布局

  九宫格布局----父盒子

            display: flex;             flex-wrap: wrap;     九宫格布局----子盒子             width: calc(calc(100% / 3) - x);             margin: x/2;   3、渲染页面 数据渲染,比较简单,不多讲     五、个人中心   1、没有难点,注意的地方就是,预览图片时,图片地址必须是http请求,不能为本地  

wx.previewImage({
      urls: urlList //urlList是数组
})

 

2、退出登录要清空缓存

 

六、详情页面

需求:展示设备详情数据,设备差不多100种左右,每个设备的ui不同;重点来了,不同设备详情页面可以左右滑动到下一个页面(顺序为首页的顺序,滑动效果轮播图那样)

天哪这一个页面得写多少代码啊啊啊...,后台接口只有获取设备列表和根据设备id获取详情数据,且格式由于是转发不能修改

额,只能一点点写了,

1、直接把官方的swiper组件拿过来开撸,为了减少请求直接把首页请求的设备列表list传到的详情页并保存

2、初始化,根据传递的设备id,请求详情数据,把需要的数据绑定到list数组下对应的设备数据对象中

3、dom结构是根据不同设备ui进行了划分,共有的和私有的,通过wx-if来进行要渲染的内容

4、要区分当前详情数据第几页,这里首先把拿到的list数组过滤,得到有详情页的数据列表(有些设备无详情页),然后循环查找当前的设备id,循环的key+1值就是第几个设备,并且把当swiper组件的当前页页设置为key。

5、左右滑动的时候,根据滑动后触发事件,获得的索引作为list的索引,拿到下个设备的id,然后进行渲染(渲染前清除上个设备的dom)

6、这里且套了多次循环,主要还是请求到的数据格式不理想,导致了写了很多处理格式的代码

7、测试,发现bug,左右来回滑动很快的时候,停下来后页面会不停抖动,查了下是组件的bug。

解决方式:对滑动事件触发后 的触发源做判断,如果是touch则进行页面渲染,解决了抖动问题;

测试发现出现无法滑动的bug,分析是滑动后更改当前页导致

解决方式:做节流,当触发滑动事件后到渲染数据这段时间禁止页面滑动,当渲染完成才允许滑动,现在就是如何禁止页面滑动,组件没这个属性,想到通过添加一个透明层来阻止滑动执行(有更好的方法的小伙伴可以分享下)。

 

7、需要增加要实时更新数据和上报推送消息-------webSocket

上网找了下有很多现成的轮子,看了下很简单。

附上原文地址:https://www.cnblogs.com/nanyang520/p/11200857.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连接");
          }
        }
      )
    }
  }

 

8、需求更改 要用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的问题涉及的一些知识点,以后有时间在补存或另写一章。

 

发表评论

相关文章