小程序字段方法监听

83 篇文章 1 订阅
52 篇文章 0 订阅

一、小程序字段监听 

 

utils/listener/src/events.js

/**

 *  Declare : 订阅事件全局常量 及 注释

 */

'use strict';

module.exports = {

  CANCEL_ORDER: 'CANCEL_ORDER',              // 取消事件

}

 utils/listener/src/listener.js

/**
 * declare: 订阅 & 发布
 */

"use strict";
import uuid from '@/utils/uuid';

let listenerMap = new Map();

// 监听某个事件
function listen({event, id, maintain, callback}) {
  if(!event || typeof callback !== 'function') return;

  if(!listenerMap.has(event)) {
    listenerMap.set(event, []);
  }

  listenerMap.get(event).push({
    id,
    maintain,
    callback
  });
}

function dispatch(event, arg) {
  if (listenerMap.has(event)) {
    let listenerArr = listenerMap.get(event);
    listenerArr = listenerArr.filter((listener) => {
      listener.callback(arg);
      return listener.maintain;
    });
    if(listenerArr.length === 0) {
      listenerMap.delete(event);
    }
  }
}

// 订阅事件
function subscribe(event, maintain = false) {
  if(!event) return console.error('event can not be empty');

  let id = uuid();

  return {
    event,
    listen: function (callback) {
      listen({
        event,
        id,
        maintain,
        callback
      });
    },
    unsubscribe: function () {
      unsubscribe(event, id);
    }
  }
}

// 取消订阅
function unsubscribe(event, id) {
  if(listenerMap.has(event)) {
    const listenerArr = listenerMap.get(event);
    let index = listenerArr.findIndex((listener) => listener.id === id);
    if(index >= 0) {
      listenerArr.splice(index, 1);
    }
  }
}

export default {
  subscribe,
  dispatch
}
 

 utils/listener/index.js

'use strict';

import listener from './src/listener';

import events from './src/events';

export default listener;

export {events};

utils/uuid.js 

/**
 *  Declare : 生成唯一id
 */

"use strict";

let ORIGINAL = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';
let alphabet = '';
let timeStamp = '';
let timeStampBit = 0;
let bit = 16;

let ZERO = '';

let prevSecond = '';
let order = 1;

function uuid() {
  if(!alphabet || !timeStamp) {
    init();
  }

  const seconds = Math.floor((Date.now() - timeStamp) / 1000);

  if(prevSecond === seconds) {
    order++;
  } else {
    prevSecond = seconds;
    order = 1;
  }
  const offset = random(alphabet.length);

  return (
    padStartWithZERO(encode(seconds, offset))
    + encode(order, offset)
  );
}

function init() {
  const year = new Date().getFullYear();
  timeStamp = Date.UTC(year, 0, 1, -8, 0, 0);
  timeStampBit = encode(365 * 24 * 3600);

  shuffle();

  ZERO = alphabet[0];
}

function shuffle() {
  const alphabetSet = new Set();

  while (alphabetSet.size < bit) {
    const randomNum = random(ORIGINAL.length);
    alphabetSet.add(ORIGINAL[randomNum]);
  }

  alphabet = [...alphabetSet].join('');
  return alphabet;
}

function encode(number, offset = 0) {
  var loopCounter = 0;
  var done;

  var str = '';

  while (!done) {
    str = str + lookup(((number >> (4 * loopCounter)) & 0x0f), offset);
    done = number < (Math.pow(bit, loopCounter + 1));
    loopCounter++;
  }
  return str;
}

function lookup(index, offset = 0) {
  index = (index + offset) % alphabet.length;
  return alphabet[index];
}

function padStartWithZERO(num = 0, length = timeStampBit) {
  let result = String(num);

  let diff = length - String(num).length;
  if(diff > 0) {
    while(result.length < length) {
      result = ZERO + result;
    }
  }

  return result;
}

function random(max = 1) {
  const randomNum = Math.floor(Math.random() * max);
  if(randomNum === random._randomNum) {
    return random(max);
  } else {
    random._randomNum = randomNum;
    return randomNum;
  }
}

export default uuid;
export {encode};
export {shuffle};
export {padStartWithZERO};

使用 

传:

cancel() {
        const {id} = this.detail
        cancelOrder({id}).then(res => {
          // 返回上一页
          listeners.dispatch(events.CANCEL_ORDER)
          uni.navigateBack()
        })
      },

接:
    import listeners from '@/utils/listener/index'
    import { events  } from '@/utils/listener/index'

    onLoad() {
            this.listenCancelOrder = listeners.subscribe(events.CANCEL_ORDER, true)
            this.listenCancelOrder.listen((data)
=> {
                this.active = '0'
                this.orderList = []
                this.pageIndex = 1
                this.loadData()
            })
        },
        onUnload() {
            this.listenCancelOrder.unsubscribe()
        },

二、信息存储

utils/auth.js 

module.exports = {
  "COOKIE": "USER_COOKIE",                   // 用户的登录凭证 
  'AUTHORIZED': 'AUTHORIZED',                // 用户是否授权过小程序
  'LOGGED_IN': 'LOGGED_IN',                  // 用户是否登录
  'REGISTERED': 'REGISTERED',                // 用户是否已经注册过小程序
  'VISIT_GUIDE': 'VISIT_GUIDE',              // 是否第一次访问小程序
}

utils/systemConstant.js 

/**
 * 存储用户id
 */

import constant from '@/utils/systemConstant'

export function setToken(token) {
  uni.setStorageSync(constant.COOKIE, token);
}

export function getToken() {
  return uni.getStorageSync(constant.COOKIE)
}

export function removeToken() {
  uni.removeStorageSync(constant.COOKIE)
}

export function setLogIn(val) {
  uni.setStorageSync(constant.LOGGED_IN, val);
}

export function getLogIn() {
  return uni.getStorageSync(constant.LOGGED_IN)
}

export function removeLogIn() {
  uni.removeStorageSync(constant.LOGGED_IN)
}

/global.js

'use strict'

const globalData = {
  set: function(path, value, api) {
    path && (globalData[path] = value)
    return true
  },
  get: function(path) {
    return path ? globalData[path] : globalData
  },
  delete: function(path) {
    delete globalData[path]
    return true
  }
}

export default globalData

使用:

utils/wechat.js 

/**
 * 微信登录操作
 */

"use strict";
import config from 'config';
import constant from '@/utils/wechat'
import { getToken, setToken, setLogIn } from '@/utils/auth'
import { set } from '@/global'
import { onLogin, getPhone, detailUser } from '@/api/user'
import listeners from '@/utils/listener/index'
import { events } from '@/utils/listener/index'

// 获取登录凭证code
export function getCode() {
  return new Promise((resolve, reject) => {
    uni.login({
      success: function(res) {
        resolve(res.code);
      },
      fail: function(res) {
        reject(res);
      }
    })
  })
}

// 微信code登录
export function wechatLogin() {
  return new Promise((resolve, reject) => {
    getCode()
      .then((code) => {
        // 用code获取用户信息
        return onLogin({code})
      })
      .then((data) => {
        // 如果上一次登录的方式为微信登录,则进入小程序可直接用微信code登录
        // 若不是说明上次登录为手机号登录或退出登录
        const loginType = uni.getStorageSync('loginType')

        if(!loginType) {
          uni.removeStorageSync('WechatUserId')
          uni.removeStorageSync('phone')
          uni.setStorageSync('registered', false)
        } else if(loginType == 'wechat') {
          loginCallback(data)
        } else {
          // 手机号登录(防止因用户删除但是微信缓存中的用户信息未更新)
          const userId = uni.getStorageSync('WechatUserId')
          if(userId) {
            detailUser({id: userId}).then(res => {
              loginCallback(res)
            })
          }
        }
        
        // 判断当前微信用户是否注册过
        if(data.user) {
          uni.setStorageSync('wechatRegistered', true)
          uni.setStorageSync('payOpenId', data.openid)
        } else {
          // 未微信授权的情况下
          uni.setStorageSync('wechatRegistered', false)
          uni.setStorageSync('payOpenId', data.openid)
        }
        resolve(data);
      })
      .catch((err) => {
        loginFail(err);
        reject(err);
      })
  })
}

export function openSetting() {
  return new Promise((resolve) => {
    uni.openSetting({
      success: function(res) {
        resolve(res.authSetting);
      }
    })
  })
}

// 根据获取的手机号授权登录
export function cellphoneAuthLogin(code, params = {}) {
  return new Promise((resolve, reject) => {
    onLogin({code})
      .then((data) => { 
        if(data.sessionId) {
          return getPhone({
            sessionId: data.sessionId || null,
            encryptedData: params.encryptedData || null,
            iv: params.iv || null,
          })
        } else if(data.user) {
          return wechatLogin()
        }
      })
      .then((data) => {
        if(data.phoneNumber) {
          return wechatLogin()
        } else if(data.user) {
          loginCallback(data);
          resolve(data);
        }else {
          reject(data)
        }
      })
      .then((data) => {
        loginCallback(data);
        resolve(data);
      })
      .catch((err) => {
        loginFail(err);
        reject(err);
      })
  });
}

// 登录成功的回调
export function loginCallback(data) {
  const user = data.user || data.response

  // 获取到用户信息,即为用户注册(登录)成功,触发登录成功的监听事件
  listeners.dispatch(events.LOGIN)
  if(user) {
    uni.setStorageSync('WechatUserId', user.id)
    uni.setStorageSync('phone', user.phone)
    uni.setStorageSync('registered', true)
  } else {
    uni.removeStorageSync('WechatUserId')
    uni.removeStorageSync('phone')
    uni.setStorageSync('registered', false)
  }
}

export function loginFail(data) {
  // console.log(data)
}

// 注销登录
export function logOut() {
  set(constant.LOGGED_IN, false);
  setLogIn(false)
  wx.redirectTo({
    url: '/pages/login/index'
  })
}

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值