微信小程序监听全局变量/websocket实现动态消息提示

2,850 阅读2分钟

项目需求:

微信小程序,社区功能,个人发表帖子,当帖子得到评论、赞、收藏时需要做一个动态消息提示,用消息数量红点的形式动态提示用户收到新的消息

实现思路:

  1. 当用户进入微信小程序时,发送一个get请求,得到未读消息数量,用红点提示用户未读消息数量
  2. 同时建立一个websocket连接,在用户正在使用微信小程序的过程中,如果帖子得到回复,动态提醒用户
  3. 当用户点击阅读消息后,发送一个get请求,表示已经阅读消息,将未读消息数量置0

注意

红点提示数字需要动态改变,当用户进入微信小程序时,根据get请求返回的未读消息数量设置,当用户点击阅读消息后,去除红点,当用户在使用小程序过程中收到消息时,红点动态改变

红点有两处

  • 一处是tabbar“我的”右上角添加红点;微信小程序设置红点连接:developers.weixin.qq.com/miniprogram… 这处可以通过websokect;在收到websokect信息时,在app.js动态改变红点数字大小
  • 一处是“我的”页面,消息上面添加红点,这处需要监听全局变量,因为app.js没法控制页面的数据,页面也不能动态获得globalData

代码实现:

app.js

const wsInit = require('./utils/websocket');
App({
  onLaunch: function () {
    this.globalData = {
      userInfo: null,
      _newMsgNum: 0, //新消息数量
      data: {} //用来监听全局变量 
      //后面业务可能涉及多个变量的监听,如果只有一个变量监听,可传递单个值即可
    }

    let userInfo = wx.getStorageSync('userInfo');
    if (userInfo) {
      this.globalData.userInfo = userInfo;
      wsInit(userInfo.id);//建立websocket连接
      this.getNotredMsgNum();//发送get请求获取未读消息数量
      this.receiveWsMsg();//websokect接收消息
    }
  },
  async getNotredMsgNum() {
    let dataUrl = `/msg/notReadCount/${this.globalData.userInfo.id}`;
    let params = {
      host: '……',
      path: dataUrl,
      method: 'GET'
    }
    let data = await fetch(params);
    this.globalData._newMsgNum = data.data;
    
    if (data.data != 0) {//当消息数量不为0时
      this.globalData.data = { //用来监听全局变量
       _newMsgNum: data.data
      }
      wx.setTabBarBadge({//设置红点
        index: 3,//tabbar index
        text: this.globalData._newMsgNum.toString()
      })
    }
  },
  receiveWsMsg() {//当收到websocket消息时,
    let that = this;
    wx.onSocketMessage(res => {
      try {
        let data = JSON.parse(res.data);
        this.toast('您有新消息哦,请注意查看');
        this.globalData.data = { //用来监听全局变量
          _newMsgNum: ++this.globalData._newMsgNum //在原有数量上加一
        }
        wx.setTabBarBadge({//设置红点
          index: 3,//tabbar index
          text: this.globalData._newMsgNum.toString()
        })
      } catch (error) {}
    })
  },
  
  // 监听全局变量
  watch: function (method) {
    var obj = this.globalData;
    Object.defineProperty(obj, "data", {//“data”对应上面globalData中的data
      configurable: true,
      enumerable: true,
      set: function (value) {//动态赋值,value为上面globalData中的data
        this._newMsgNum = value._newMsgNum;//this指globalData
        method(value);
      },
      get: function () {//获取全局变量,直接返回全部
        return this.globalData
      }
    })
  }
})

/pages/mine/index.js 消息红点提示页面

const app = getApp();
Page({
  data: {
    newMsgNum: 0,
  }
  onLoad: function (options) {
    getApp().watch(this.watchBack)//添加监听以及指定监听回调函数
    //如果其他页面修改了app.js中的_newMsgNum值,就会触发回调函数
  },
  watchBack: function (value) {//value为app.js中watch方法中的set,返回整个globalData
    this.setData({
      newMsgNum: value._newMsgNum
    })
  },
  onShow: function () {//每次显示页面时
    this.setData({
      newMsgNum: app.globalData._newMsgNum
    })
    if (app.globalData._newMsgNum == 0) {//在消息数量为0是移除tabbar红点
      wx.removeTabBarBadge({
        index: 3,
      })
    }
  }
})

/pages/message/index.js 读消息页面

Page({
  data: {
    newMsgNum: 0,
  }
  onLoad: function (options) {
    this.readMsg();//发送get请求
  },
  async readMsg() {
    let dataUrl = `/community/msg/read/${app.globalData.userInfo.id}`;
    let params = {
      host: '......',
      path: dataUrl,
      method: 'GET'
    }
    await fetch(params);
    app.globalData._newMsgNum = 0; //清0
  },
})