• 微信小程序开发的坑


    最近做了一个小程序,顺利上线。(纯属自娱自乐,看网上说的审核不好过,就想着看运气喽,实在不行就多提两次。谁知道很快就审核过了,运气还行,不过后面提交因为进入的时候必须要授权,被要求整改)有兴趣的可以扫码体验(见文末)。这里我总结分享一下我遇到的坑,以及还没有解决的问题(文中方法不一定最优),欢迎大家留言讨论

    数据库权限

    我是用云开发自带的数据库来存储数据(当然你可以用自己的,我没这么做,所以不参与讨论),那么这就存在一个问题,数据库的默认权限是:仅创建者可读写。然后在页面js里面很可能就获取、修改不了数据,也就是除了你,其他人访问页面都访问不了数据。
    ps:我有一次忘了这个,然后找哪里出问题了查不到数据,查了好久

    解决方法:
    a. 更改数据库的权限,使其能够读或写
    b. 对于操作数据库的动作全放到云函数中去

    动态监听数据库

    我有一个好友列表,希望动态看到好友状态,所以监听好友状态变化了,就重新获取好友列表

    //创建监听器
    const watcher = db.collection('T_STATUS').where({
              openId: db.command.in(friendsId)
            }).field({//只监听这个字段
              updateDate: true
            }).watch({
              onChange: function (snapshot) {
                xxx
              },
              onError: function (err) {
                console.error('the watch closed because of error', err)
              }
            })
          }
    //关闭监听器
    watcher.close()
    

    本着监听应该保证获取最少数据的原则,我只监听了所有好友的updateDate这个字段。然后在用户任何状态变化的时候都更新这个字段,达到有效监听

    数据库的联表查询

    其实也不属于联表查询了,表A是用户表,表B是用户的好友表,表c是消息记录表。用以下方法一次性查出每个好友发送给你的消息数。不过,该方法显得很笨拙。

    var friendList = []
    //获取关联的好友详细信息
    for (let i = 0, length = friends.length; i < length; ++i) {
      await Promise.all([
        db.collection('T_A').where({
          openId: friends[i].friendId,
        }).get(),
        db.collection('T_B').where({
          openId: friends[i].friendId
        }).get(),
        db.collection('T_C').where({//好友发给自己的未读消息数
          sendFrom: friends[i].friendId,
          sendTo: friends[i].ownId,
          readed: false
        }).count()
      ]).then(([user, status, num]) => {
        event.friendList.push({
          ...friends[i],
          user: user.data[0],
          status: status.data[0],
          unreadNum: num.total
        })
      }).catch(err => {
        console.log(err)
      })
    }
    

    页面引入定义的工具函数

    在wxs文件(/utils/app.wxs)中定义函数

    var formatTime = function (time) {
      return (time/60 > 9 ? parseInt(time/60) : "0"+parseInt(time/60)) + ":" + (time%60 > 9 ? time%60 : "0"+time%60);
    }
    
    //  要引用这个文件的函数或者变量,除了在要引用的的js文件中模块化之外(var utils=require('js地址')),
    // 在被引用的的js中要通过 module.exports={a:a}作为面向对象的变量输出函数如下:
    module.exports = {
      formatTime: formatTime
    }
    

    在wxml文件中引入工具函数就可以使用

    <wxs src="../../utils/app.wxs" module="utils" />
    {{utils.formatTime()}}
    

    再记两个不错的工具
    1.日历插件:https://github.com/bingyang519/wxMiniProgram.git
    2.图表插件:https://blog.csdn.net/weixin_40709898/article/details/81020562
    注:图表插件的折线图选curve线型,两个数值相差较大,会出现正值跑到负轴的情况

    用到的几个页面加载方法

    onLoad:监听页面加载
    onShow:监听页面显示
    onHide:监听页面隐藏
    onUnload:监听页面卸载
    onShareAppMessage:用户点击右上角转发,或者控件有open-type="share"
    

    分享应用

    主要是自定义图片,这个没啥技巧性

        //分享应用给好友
        onShareAppMessage: function (options) {
          var that = this;
          var shareObj = {
           title: "这是一个小程序",
           path: '/pages/index/index',        // 默认是当前页面,必须是以‘/’开头的完整路径
           imageUrl: '/images/sharePhoto.png',    
          }
          return shareObj;
        }
    

    主要说一下的是imageURL, 不是imgURL,看到网上有人说后面这个(我就被这个误导了),希望大家不要再被误导了,是前面那个

    两个定时器

    1. 我做的是个类定时器工具,直接用到了计时器
    //启动计时器
    var interval = setInterval(
           function () {
             xxx//每一秒执行
           }, 1000);
    //清除计时器
    clearInterval(interval)
    

    这个计时器存在一个问题,小程序切到后台,它就停止工作了,进入前台才会工作。

    解决办法:
    a.在onHide方法里面停止计时器,并记下停止时的时间戳
    b.在onShow方法里开启计时器,并加上停止的时间

    1. 用到了倒计时工具,因为页面有个打卡按钮,打卡后字会变;所以设置了这个倒计时,设置了现在到下一天凌晨的时间间隔后,将按钮的字和状态变掉
    timer = setTimeout(function () {
           xxx//下一天的凌晨执行
         }, twelveClock);
    

    这个遇到的问题是怎么也获不到东八区和下一天凌晨的时间

    解决办法:
    a东八区时间:后文有提到,还未解决
    b下一天凌晨时间:var nextday = new Date(new Date(date.getTime() + 10006060*24).setHours(0,0,0,0));

    列表里的输入和发送事件

    我在好友列表里的每一行都,放了一个输入框和发送按钮,因为好友列表是动态的,所以这些事件也都是动态的,这种页面实现这个功能还是有点儿挑战的。
    首先,动态列表就存在遍历list,它的默认下标index可一个取到。控件存在data-key属性,key对应变量名,在触发事件里可以得到传过去的值;input控件存在一个bindInput属性,可以配一个方法,监听输入事件

    //wxml
    <view class="friends" wx:for="{{friendList}}"
          <view class="message">
            <input class="weui-input" maxlength="200" placeholder="留言..." adjust-position="true" data-index="{{index}}" bindinput="messageInput" value="{{item.message}}"/>
          </view>
    
          <view class="send" bindtap="send" data-index="{{index}}">
            <image src="/images/send.png"></image>
          </view>
    </view>
    
    //js
    messageInput: function(event) {
      //console.log(event.currentTarget.dataset)
      var index = event.currentTarget.dataset.index
      this.data.friendList[index].message = event.detail.value
      this.setData({
        friendList: this.data.friendList
      })
    },
    //发送消息
    send: function(event) {
      //console.log(event.currentTarget.dataset)
      var index = event.currentTarget.dataset.index
      console.log(this.data.friendList[index].message)
      ...
     }
    

    未解决的问题

    云函数中的日期时区问题:
    在云函数中用到日期的时候,我将new Date()转成东八区时间(至于怎么转,大家可以百度),这时候就存在了三个不同的时间:1.云函数打印日志的时间是北京时间前8个小时;2.我转的时间是北京时间;3.把我转的时间存到数据库,显示的是北京时间加上8个小时。你问我问什么要转东八区时间,因为我看到了时间不一致,病急乱投医。

    Tom和Jerry的时光

  • 相关阅读:
    设计模式之模式方法模式
    Extjs 分页多选的实现
    设计模式之策略模式
    oracle 12c 报错 ora-03137 来自客户机的格式错误的TTC包被拒绝
    设计模式之状态模式
    设计模式之装饰者模式
    设计模式之代理模式
    设计模式之单例模式
    从reduce函数说起...
    Django View(视图系统)
  • 原文地址:https://www.cnblogs.com/so-easy/p/11839280.html
Copyright © 2020-2023  润新知