• 微信小程序开发的坑


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

    数据库权限

    我是用云开发自带的数据库来存储数据(当然你可以用自己的,我没这么做,所以不参与讨论),那么这就存在一个问题,数据库的默认权限是:仅创建者可读写。然后在页面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的时光

  • 相关阅读:
    bzoj 1017 魔兽地图DotR
    poj 1322 chocolate
    bzoj 1045 糖果传递
    poj 3067 japan
    timus 1109 Conference(二分图匹配)
    URAL 1205 By the Underground or by Foot?(SPFA)
    URAL 1242 Werewolf(DFS)
    timus 1033 Labyrinth(BFS)
    URAL 1208 Legendary Teams Contest(DFS)
    URAL 1930 Ivan's Car(BFS)
  • 原文地址:https://www.cnblogs.com/so-easy/p/11839280.html
Copyright © 2020-2023  润新知