微信小程序监听用户登录事件的实现方法

最近在开发小程序,小程序既需兼顾针对新用户的内容预览,又要为注册用户提供服务,简单梳理下,基本需求如下:

  • 小程序共三个tab页,所有用户都可以浏览首页内容,了解我们可以提供的优质服务;
  • 进入其他两个页面之后,如果用户没有登录,那就显示登录按钮,如果登录了,则显示服务内容;
  • 用户在一个页面登陆之后,全局生效。

就这么个看起来很简单的需求,也经过了如下迭代:

  • 将登录状态和凭据存储在 App.globalData.authorize 中,每个需要授权的页面 onload 生命周期检查 App.globalData.authorize.authorized ,为 true 时渲染服务内容,为 false 则显示登录按钮;
  • 但如果打开了需要授权的页面 A 但是没有登录,再打开页面 B 登录,这时候回到 A 页面,登录按钮赫然在眼,这是因为 A 页面的 onload 回调函数只执行了一次;
  • 为了能在 A 页面及时共享 B 页面登录后的状态,在 A 页面的 onshow 生命周期里再获取了一次登录状态,但这样一来,打开 A 页面的时候,会出现短暂的白屏,用户甚至有可能看到按钮变成服务内容的整个过程。

翻遍小程序 API 文档 ,也没有发现用于监听登录的生命周期,就算有也用不了,因为我们有着自己的账号体系,服务端认证完毕才算真正的登录成功。

所以我决定自己包装原有的 Page 函数,添加一个 onauth 生命周期——

首先是自定义登录事件的触发与监听,官方的EventChannel需要向后兼容,横竖是个订阅回调,那我还不如自己撸一个得了:

/**
 * @file utils/event.js
 */

/**
 * @const EMPTY_HANDLER
 * @desc 空事件回调,被取消事件将被指向此函数
 */
const EMPTY_HANDLER = () => {};

/**
 * @const eventSet - 事件监听函数集
 */
const eventSet = {
 authorize: []
};

/**
 * @function emit - 发送全局事件
 * @param {String} type - 事件类型
 * @param {Object} event - 事件对象
 */
export const emit = (type, event) => (eventSet[type] || []).forEach(item => item(Object.freeze(event)));

/**
 * @function on - 注册全局事件
 * @param {String} type - 事件类型
 * @param {Function} callback - 事件回调函数
 */
export const on = (type, callback) => {
 if (!eventSet[type]) {
  eventSet[type] = [];
 }

 if (!callback instanceof Function) {
  throw new Error('callback must be a Function!');
 }

 return eventSet[type].push(callback)
};

/**
 * @function off - 取消对某事件的监听
 * @param {String} type - 事件类型
 * @param {Number} id - 需要取消的事件ID,即 registEvent 所返回的值
 */
export const off = (type, id) => {
 if (!eventSet[type]) return

 eventSet[type][id - 1] = EMPTY_HANDLER

 // 如果某类事件已经全被取消的话,将其置为空数组
 const noListener = !eventSet[type].reduce((pre, cur) => (cur && cur === EMPTY_HANDLER) || pre, false);
 if (noListener){
  eventSet[type] = []
 };
}

然后是对 Page 函数的魔改:

/**
 * @file utils/auth-page.js
 */

import { on } from '/event.js';

export const AuthPage = function(options){
 const { onAuth, data, onLoad } = options;
 const userInfo = {
  nickName: '', // 昵称
  account: '', // 账号
  avatar: { // 头像
   small: '',
   middle: '',
   large: ''
  },
  title: 'student', // 头衔
  phoneNumber: 0, // 电话号码
  gender: 'secret', // 性别
  'class': '' // 班级
 }

 if (options.data){
  options.data.authorized = false;
  options.data.userInfo = userInfo
 } else {
  options.data = {
   authorized: false,
   userInfo: userInfo
  }
 }

 /**
  * 仍旧调用原始的 Page 方法
  */
 Page(Object.assign(
  options,
  {
   onLoad: function () {
    const { authorize, userInfo } = getApp().globalData;

    // 执行开发者期望的 onload 事件
    onLoad instanceof Function && onLoad.bind(this)(arguments);

    // 页面初始化时,若已经授权,直接执行授权回调
    // 否则将授权回调注册为授权事件回调
    if (onAuth instanceof Function){
     if (authorize.authorized){
      onAuth.bind(this)({
       type: 'authorize',
       authorized: true,
       token: authorize.token,
       userInfo: userInfo
      });
     } else {
      on('authorize', onAuth.bind(this));
     }
    }
   }
  }
 ));
}

最后,在登录组件的里:

import { emit } from '../../utils/event.js';

wx.login({
  success: res => {
    // ...这里省略了一些复杂的登录流程
    getApp().globalData.authorize = {
      authorized: true
    };
    emit('authorize', res);
  }
})

然后,在两个需要登录的 tab 页引入 AuthPage 替换原有的 Page 函数,并在配置项里写 onAuth 回调,就可以监听登录事件了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 微信小程序批量监听输入框对按钮样式进行控制的实现代码

    在input组件上绑定data-model="xxx" bindinput="inputWatch",监听输入框输入: <input placeholder="请输入6~12位密码" name="password" value="{{password}}" data-model="password" bindinput="inputWacth" type=&qu

  • 微信小程序实现拖拽 image 触摸事件监听的实例

    微信小程序实现拖拽 image 触摸事件监听的实例 需要做个浮在scroll-view之上的button.尝试了一下. 实现效果图: Android中也会有类似移动控件的操作.思路差不多.获取到位移的X Y 的变量,给控件设置坐标. 1.index.wxml <image class="image-style" src="../../images/gundong.png" bindtap="ballClickEvent" style=&qu

  • 微信小程序image图片加载完成监听

    需求 在应用中显示的图片很多情况不满足业务需求,我们需要动态根据图片的宽高进行缩放或加载中显示的缺省图片,这是我没就需要监听图片加载完成回调,来看看微信小程序怎么实现图片加载完成回调. 实现 1. 绑定回调 通过image标签的bindload属性绑定图片加载完成回调函数,src根据图片加载是否完成绑定是否显示缺省图: <image src='{{loadComplete?srcImagePath:defaultImagePath}}' bindload="imageLoad"/

  • 微信小程序 实现拖拽事件监听实例详解

    微信小程序 拖拽监听功能: 在软件开发或者 APP应用开发的时候,经常会遇到拖拽监听,最近自己学习微信小程序的知识,就想实现这样的拖拽效果,这里就记录下. 需要做个浮在scroll-view之上的button.尝试了一下. 上GIF: Android中也会有类似移动控件的操作.思路差不多.获取到位移的X Y 的变量,给控件设置坐标. 1.index.wxml ../images/gundong.png" bindtap="ballClickEvent" style="

  • 微信小程序在其他页面监听globalData中值的变化

    前言 这几天去面试,多次碰到同一个知识点.而且有一次面试挺有趣的,是关于小程序的.共有3个问题. 1.小程序中Page.watch()方法是做什么用的? 2.小程序中如何在其他页面中监听到globalData中值的变化? 3.如果在app.js执行登录部分的代码,由于时序问题,如何处理其他页面请求时未获取到身份识别标记的情况.(session,userid等).(大意是:怎么能够保证其他页面请求是在登录之后?) 知识点 有经验的同学可能一下子就看出来了,这其实说的是同一个东西,那就是Object

  • 微信小程序 监听手势滑动切换页面实例详解

    微信小程序 监听手势滑动切换页面实例详解 1.对应的xml里写上手势开始.滑动.结束的监听: <view class="touch" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd" ></view> 2.js: var touchDot = 0;//触摸时的原点 var time = 0;// 时

  • 微信小程序page的生命周期和音频播放及监听实例详解

    一.界面的生命周期 /** * 监听页面加载, * 页面加载中 */ onLoad:function(){ var _this = this console.log('index---------onload()') /** * 监听音乐播放 */ wx.onBackgroundAudioPlay(function() { console.log('onBackgroundAudioPlay') }), /** * 监听音乐暂停 */ wx.onBackgroundAudioPause(func

  • 微信小程序全局变量改变监听的实现方法

    问题来源 最近工作需要写小程序页面,其中有个页面情况为:父页面中包含了一个组件页面,组件页面中又包含了另外一个组件页面. 需求为:点击最后一个组件页面中的一个view,需要显示最外层父页面中的一个弹出层,并且动态的展示值,这个值的来源就是最后一个组件页面中的内容. 处理办法 当时想到的就是使用全局变量,在 app.js 中定义好全局变量,点击组件页面时就修改全局变量的值,父页面同样使用全局变量的值,这样一来就可以动态打开/关闭弹出层且传递值了. 下面先看看 app.js 中怎么定义的: glob

  • 微信小程序监听用户登录事件的实现方法

    最近在开发小程序,小程序既需兼顾针对新用户的内容预览,又要为注册用户提供服务,简单梳理下,基本需求如下: 小程序共三个tab页,所有用户都可以浏览首页内容,了解我们可以提供的优质服务: 进入其他两个页面之后,如果用户没有登录,那就显示登录按钮,如果登录了,则显示服务内容: 用户在一个页面登陆之后,全局生效. 就这么个看起来很简单的需求,也经过了如下迭代: 将登录状态和凭据存储在 App.globalData.authorize 中,每个需要授权的页面 onload 生命周期检查 App.glob

  • Laravel 微信小程序后端实现用户登录的示例代码

    接上篇微信小程序后端搭建:分享:Laravel 微信小程序后端搭建 后端搭建好后第一件事就是用户登录认证,简单实现微信小程序登录认证 1.user 模型 use Laravel\Passport\HasApiTokens; 新增 use HasApiTokens, Notifiable; protected $fillable = [ 'id', 'name', 'email', 'email_verified_at', 'username', 'phone', 'avatar',//我用来把微

  • 微信小程序中做用户登录与登录态维护的实现详解

    总结 大家都知道,在开发中提供用户登录以及维护用户的登录状态,是一个拥有用户系统的软件应用普遍需要做的事情.像微信这样的一个社交平台,如果做一个小程序应用,我们可能很少会去做一个完全脱离和舍弃连接用户信息的纯工具软件. 让用户登录,标识用户和获取用户信息,以用户为核心提供服务,是大部分小程序都会做的事情.我们今天就来了解下在小程序中,如何做用户登录,以及如何去维护这个登录后的会话(Session)状态.下面来看看详细的介绍: 在微信小程序中,我们大致会涉及到以下三类登录方式: 自有的账号注册和登

  • 微信小程序如何获取用户信息

    最近在研究微信小程序怎么玩的.接触后发现好多的坑. 比如在浏览器中我们可以通过document.getElementById 获取到页面的DOM对象.而在微信小程序中是获取不到DOM对象的.document.getElementById() 直接报错 getElementById not function 我也是醉了.不支持这个好多有趣的功能不能实现了. 言归正传,我谈下获取用户信息的感想. 有两种获取用户信息的方案. 1.不包含敏感信息openId 的json对象(包含:nickname.av

  • 微信小程序学习笔记之登录API与获取用户信息操作图文详解

    本文实例讲述了微信小程序学习笔记之登录API与获取用户信息操作.分享给大家供大家参考,具体如下: 前面介绍了微信小程序跳转页面.传递参数获得数据,这里来分析一下登录API与获取用户信息操作方法. [小程序登录]wx.login() app.js: App({ onLaunch: function () { // 登录 wx.login({ success: function (res) { if (res.code) { //发起网络请求 wx.request({ url: 'https://w

  • 微信小程序如何获取用户头像和昵称

    本文介绍了微信小程序如何获取用户头像和昵称,分享给大家,具体如下: 代码user.wxml: <view > <view> <image class="avatar" src='{{userInfo.avatarUrl}}'></image> <view class="nickname">{{userInfo.nickName}}</view> </view> </view&g

  • 微信小程序跨页面数据传递事件响应实现过程解析

    这篇文章主要介绍了微信小程序跨页面数据传递事件响应实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在实际工作中有很多场景需要在第二个页面中将用户操作之后的将数据回传到上一页面.接下来将我的方案分享给小伙伴. 本次示例采用 uni-app 框架和 weui 样式库 实现思路 创建一个 Emitter,用于事件处理 创建一个 ... 在实际工作中有很多场景需要在第二个页面中将用户操作之后的将数据回传到上一页面.接下来将我的方案分享给小伙

  • 微信小程序getPhoneNumber获取用户手机号

     微信小程序getPhoneNumber获取用户手机号 小程序中有很多地方都会用到注册用户信息的地方,用户需要填写手机号等, 有了这个组件可以快速获取微信绑定手机号码,无须用户填写. 1.getPhoneNumber这个组件通过button来实现(别的标签无效).将button中的open-type="getPhoneNumber",并且绑定bindgetphonenumber事件获取回调. <button open-type="getPhoneNumber"

  • 在微信小程序中获取用户位置的详细过程

    目录 前言 wx.getLocation 腾讯位置服务 总结 前言 最近在学习微信小程序,在学习的过程中,有很多好玩的 API,经常点外卖的同学可能在小程序中遇到过,比如:某团.某了么都是有显示当前用户位置信息的,那么今天给大家介绍如何获取当前用户位置信息,听上去很不错,其实实践起来也不是很难. wx.getLocation 首先,我们需要来认识一下 wx.getLocation 这个 API 方法,我们先看看 微信官方文档 中是怎么说的 看我划红线的地方就可以了,文档中明确的表示这个 API

随机推荐