测试小站: 处理网 回收帮 培训网 富贵论坛 老富贵论坛

解决百度小程序之间页面通信的问题

  背景

  主要是针对小程序开发中页面之间进行通信的问题,在涉及支付的场景中,用户从页面支付入口进行跳转进行支付之后,回到原来页面,在原来的页面需要进行相应的状态刷新,比如用户身份状态、支付状态、文档或商品情况。

  遇到的问题

  在使用百度小程序的 swan.navigateBack 进行回跳页面时,API中的方法参数不支持携带参数,只支持number参数。

  所以就涉及了几个单独页面之间的通信问题。如下主要列出了几个方法,供参考。

  swan.navigateBack

  参数名类型必填默认值说明deltaNumber否1返回的页面数,如果 delta 大于现有页面数,则返回到首页1。successfunction否-接口调用成功的回调函数failfunction否-接口调用失败的回调函数completefunction否-接口调用结束的回调函数(调用成功、失败都会执行)

  解决方法

  主要有以下三种方法,实现各page之间通信。

  解决方法一:利用app.js,设置公共变量

  利用app.js的公共特性,将变量挂在APP上。

  // app.js 启动文件

  App({

  globalData: {

  isLogin: false,

  userInfo: null,

  networkError: false,

  networkType: 'none'

  }

  })

  在其他页面Page上使用时,使用:

  // test.js

  const app=getApp();

  const commonParams=app.globalData.isLogin;

  但是存在的缺点也十分明显,当数据量比较大、数据关系比较复杂时,维护会比较复杂,逻辑会很混乱。

  解决方法二:利用storage

  利用小程序的全局storage,对数据进行存取,原理类似于解决方案一。

  // 存储-异步

  swan.setStorage({

  key: 'key',

  data: 'value'

  });

  // 存储-同步

  swan.setStorageSync('key', 'value');

  // 获取-异步

  swan.getStorage({

  key: 'key',

  success: function (res) {

  console.log(res.data);

  },

  fail: function (err) {

  console.log('错误码:' + err.errCode);

  console.log('错误信息:' + err.errMsg);

  }

  });

  // 获取-同步

  const result=swan.getStorageSync('key');

  解决方法三: 利用事件中心

  利用事件中心的进行订阅和发布。

  // event.js 事件中心

  class Event {

  on(event, fn, ctx) {

  if (typeof fn !=='function') {

  console.error('fn must be a function');

  return;

  }

  this._stores=this._stores || {};

  (this._stores[event]=this._stores[event] || []).push({

  cb: fn,

  ctx: ctx

  });

  }

  emit(event, ...args) {

  this._stores=this._stores || {};

  let store=this._stores[event];

  if (store) {

  store=store.slice(0);

  for (let i=0, len=store.length; i < len; i++) {

  store[i].cb.apply(store[i].ctx, args);

  }

  }

  }

  off(event, fn) {

  this._stores=this._stores || {};

  // all

  if (!arguments.length) {

  this._stores={};

  return;

  }

  // specific event

  let store=this._stores[event];

  if (!store) {

  return;

  }

  // remove all handlers

  if (arguments.length===1) {

  delete this._stores[event];

  return;

  }

  // remove specific handler

  let cb;

  for (let i=0, len=store.length; i < len; i++) {

  cb=store[i].cb;

  if (cb===fn) {

  store.splice(i, 1);

  break;

  }

  }

  return;

  }

  }

  module.exports=Event;

  在app.js中进行声明和管理

  // app.js

  import Event from './utils/event';

  App({

  event: new Event()

  })

  订阅的页面中,使用on方法进行订阅

  // view.js 阅读页进行订阅

  Page({

  // 页面在回退时,会调用onShow方法

  onShow() {

  // 支付成功的回调,调起下载弹层

  app.event.on('afterPaySuccess', this.afterPaySuccess, this);

  },

  afterPaySuccess(e) {

  // ....业务逻辑

  }

  })

  发布的页面中,根据业务情况进行发布emit

  // paySuccess.js

  const app=getApp();

  app.event.emit('afterPaySuccess', {

  docId: this.data.tradeInfo.docId,

  triggerFrom: 'docCashierBack'

  });

  根据事件中心的发布和订阅,实现了页面之间的通信,就能实现比如页面在支付成功后回退时,页面状态的改变的场景,同时利于维护页面之间的数据关系,能通过在发布时传递参数,实现数据之间的通信。

posted @ 2021-12-21 13:59  linjingyg  阅读(119)  评论(0)    收藏  举报