最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

微信小程序頁面間通信的5種方式

 更新時(shí)間:2017年03月31日 10:44:43   作者:u3xyz  
這篇文章主要介紹了微信小程序頁面間通信的5種方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

PageModel(頁面模型)對小程序而言是很重要的一個(gè)概念,從app.json中也可以看到,小程序就是由一個(gè)個(gè)頁面組成的。

如上圖,這是一個(gè)常見結(jié)構(gòu)的小程序:首頁是一個(gè)雙Tab框架PageA和PageB,子頁面pageB, PageC。

讓我們假設(shè)這樣一個(gè)場景:首頁P(yáng)ageA有一個(gè)飄數(shù),當(dāng)我們從PageA新開PageC后,做一些操作,再回退到PageA的時(shí)候,這個(gè)飄數(shù)要刷新。很顯然,這需要在PageC中做操作時(shí),能通知到PageA,以便PageA做相應(yīng)的聯(lián)動變化。

這里的通知,專業(yè)點(diǎn)說就是頁面通信。所謂通信,u3認(rèn)為要滿足下面兩個(gè)條件:

  1. 激活對方的一個(gè)方法調(diào)用
  2. 能夠向被激活的方法傳遞數(shù)據(jù)

本文將根據(jù)項(xiàng)目實(shí)踐,結(jié)合小程序自身特點(diǎn),就小程序頁面間通信方式作一個(gè)探討與小結(jié)。

通信分類

按頁面層級(或展示路徑)可以分為:

  1. 兄弟頁面間通信。如多Tab頁面間通信,PageA,PageB之間通信
  2. 父路徑頁面向子路徑頁面通信,如PageA向PageC通信
  3. 子路徑頁面向父路徑頁面通信,如PageC向PageA通信

按通信時(shí)激活對方方法時(shí)機(jī),又可以分為:

  1. 延遲激活,即我在PageC做完操作,等返回到PageA再激活PageA的方法調(diào)用
  2. 立即激活,即我在PageC做完操作,在PageC激活PageA的方法調(diào)用

方式一:onShow/onHide + localStorage

利用onShow/onHide激活方法,通過localStorage傳遞數(shù)據(jù)。大概邏輯如下

// pageA
let isInitSelfShow = true;

Page({
 data: {
  helloMsg: 'hello from PageA'
 },

 onShow() {
  // 頁面初始化也會觸發(fā)onShow,這種情況可能不需要檢查通信
  if (isInitSelfShow) return;

  let newHello = wx.getStorageSync('__data');

  if (newHello) {
   this.setData({
    helloMsg: newHello
   });

   // 清隊(duì)上次通信數(shù)據(jù)
   wx.clearStorageSync('__data');
  }

 },

 onHide() {
  isInitSelfShow = false;
 },

 goC() {
  wx.navigateTo({
   url: '/pages/c/c'
  });
 }
});
// pageC
Page({
 doSomething() {
  wx.setStorageSync('__data', 'hello from PageC');
 }
});

優(yōu)點(diǎn):實(shí)現(xiàn)簡單,容易理解

缺點(diǎn):如果完成通信后,沒有即時(shí)清除通信數(shù)據(jù),可能會出現(xiàn)問題。另外因?yàn)橐蕾噇ocalStorage,而localStorage可能出現(xiàn)讀寫失敗,從面造成通信失敗

注意點(diǎn):頁面初始化時(shí)也會觸發(fā)onShow

方式二:onShow/onHide + 小程序globalData

同方式一一樣,利用onShow/onHide激活方法,通過讀寫小程序globalData完成數(shù)據(jù)傳遞

// PageA
let isInitSelfShow = true;
let app = getApp();

Page({
 data: {
  helloMsg: 'hello from PageA'
 },

 onShow() {
  if (isInitSelfShow) return;

  let newHello = app.$$data.helloMsg;

  if (newHello) {
   this.setData({
    helloMsg: newHello
   });

   // 清隊(duì)上次通信數(shù)據(jù)
   app.$$data.helloMsg = null;
  }

 },

 onHide() {
  isInitSelfShow = false;
 },

 goC() {
  wx.navigateTo({
   url: '/pages/c/c'
  });
 }
});

// PageC
let app = getApp();

Page({
 doSomething() {
  app.$$data.helloMsg = 'hello from pageC';
 }
});

優(yōu)點(diǎn):實(shí)現(xiàn)簡單,實(shí)現(xiàn)理解。因?yàn)椴蛔x寫localStorage,直接操作內(nèi)存,所以相比方式1,速度更快,更可靠

缺點(diǎn):同方式1一樣,要注意globalData污染

方式三:eventBus(或者叫PubSub)方式

這種方式要先實(shí)現(xiàn)一個(gè)PubSub,通過訂閱發(fā)布實(shí)現(xiàn)通信。在發(fā)布事件時(shí),激活對方方法,同時(shí)傳入?yún)?shù),執(zhí)行事件的訂閱方法

/* /plugins/pubsub.js
 * 一個(gè)簡單的PubSub
 */
export default class PubSub {
 constructor() {
  this.PubSubCache = {
   $uid: 0
  };
 }

 on(type, handler) {
  let cache = this.PubSubCache[type] || (this.PubSubCache[type] = {});

  handler.$uid = handler.$uid || this.PubSubCache.$uid++;
  cache[handler.$uid] = handler;
 }

 emit(type, ...param) {
  let cache = this.PubSubCache[type], 
    key, 
    tmp;

  if(!cache) return;

  for(key in cache) {
   tmp = cache[key];
   cache[key].call(this, ...param);
  }
 }

 off(type, handler) {
  let counter = 0,
    $type,
    cache = this.PubSubCache[type];

  if(handler == null) {
   if(!cache) return true;
   return !!this.PubSubCache[type] && (delete this.PubSubCache[type]);
  } else {
   !!this.PubSubCache[type] && (delete this.PubSubCache[type][handler.$uid]);
  }

  for($type in cache) {
   counter++;
  }

  return !counter && (delete this.PubSubCache[type]);
 }
}
//pageA
let app = getApp();

Page({
 data: {
  helloMsg: 'hello from PageA'
 },

 onLoad() {
  app.pubSub.on('hello', (number) => {
   this.setData({
    helloMsg: 'hello times:' + number
   });
  });
 },

 goC() {
  wx.navigateTo({
   url: '/pages/c/c'
  });
 }
});
//pageC
let app = getApp();
let counter = 0;

Page({
 doSomething() {
  app.pubSub.emit('hello', ++counter);
 },

 off() {
  app.pubSub.off('hello');
 }
});

缺點(diǎn):要非常注意重復(fù)綁定的問題

方式四:gloabelData watcher方式

前面提到方式中,我們有利用globalData完成通信?,F(xiàn)在數(shù)據(jù)綁定流行,結(jié)合redux單一store的思想,如果我們直接watch一個(gè)globalData,那么要通信,只需修改這個(gè)data值,通過water去激活調(diào)用。同時(shí)修改的data值,本身就可以做為參數(shù)數(shù)據(jù)。

為了方便演示,這里使用oba這個(gè)開源庫做為對象監(jiān)控庫,有興趣的話,可以自己實(shí)現(xiàn)一個(gè)。

//pageA
import oba from '../../plugin/oba';

let app = getApp();

Page({
 data: {
  helloMsg: 'hello from PageA'
 },

 onLoad() {
  oba(app.$$data, (prop, newvalue, oldValue) => {
   this.setData({
    helloMsg: 'hello times: ' + [prop, newvalue, oldValue].join('#')
   });
  });
 },

 goC() {
  wx.navigateTo({
   url: '/pages/c/c'
  });
 }
});
//pageC
let app = getApp();
let counter = 0;

Page({
 doSomething() {
  app.$$data.helloTimes = ++counter;
 }
});

優(yōu)點(diǎn):數(shù)據(jù)驅(qū)動,單一數(shù)據(jù)源,便于調(diào)試

缺點(diǎn):重復(fù)watch的問題還是存在,要想辦法避免

方式五:通過hack方法直接調(diào)用通信頁面的方法

直接緩存頁面PageModel, 通信時(shí),直接找到要通信頁面的PageModel,進(jìn)而可以訪問通信頁面PageModel所有的屬性,方法。簡直不能太cool,感謝小組內(nèi)小伙伴發(fā)現(xiàn)這么amazing的方式。有人肯定會問了,怎么拿到這個(gè)所有的PageModel呢。其它很簡單,每個(gè)頁面有onLoad方法,我們在這個(gè)事件中,把this(即些頁面PageModel)緩存即可,緩存時(shí)用頁面路徑作key,方便查找。那么頁面路徑怎么獲取呢,答案就是page__route__這個(gè)屬性

// plugin/pages.js 
// 緩存pageModel,一個(gè)簡要實(shí)現(xiàn)
export default class PM {
 constructor() {
  this.$$cache = {};
 }

 add(pageModel) {
  let pagePath = this._getPageModelPath(pageModel);

  this.$$cache[pagePath] = pageModel;
 }

 get(pagePath) {
  return this.$$cache[pagePath];
 }
 
 delete(pageModel) {
  try {
   delete this.$$cache[this._getPageModelPath(pageModel)];
  } catch (e) {
  }
 }

 _getPageModelPath(page) {
  // 關(guān)鍵點(diǎn)
  return page.__route__;
 }
}
// pageA
let app = getApp();

Page({
 data: {
  helloMsg: 'hello from PageA'
 },

 onLoad() {
  app.pages.add(this);
 },

 goC() {
  wx.navigateTo({
   url: '/pages/c/c'
  });
 },
 
 sayHello(msg) {
  this.setData({
   helloMsg: msg
  });
 }
});
//pageC

let app = getApp();

Page({
 doSomething() {
  // 見證奇跡的時(shí)刻
  app.pages.get('pages/a/a').sayHello('hello u3xyz.com');
 }
});

優(yōu)點(diǎn):一針見血,功能強(qiáng)大,可以向要通信頁面做你想做的任何事。無需要綁定,訂閱,所以也就不存在重復(fù)的情況

缺點(diǎn):使用了__route__這個(gè)hack屬性,可能會有一些風(fēng)險(xiǎn)

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

称多县| 永州市| 乃东县| 镇安县| 祁东县| 揭西县| 盐津县| 长子县| 乐平市| 岑溪市| 湘潭市| 霸州市| 保德县| 阿坝| 甘孜| 瑞丽市| 班玛县| 大方县| 鹤庆县| 临澧县| 苏州市| 康保县| 米林县| 仁寿县| 福建省| 肃南| 沧源| 津南区| 大荔县| 焦作市| 藁城市| 佛冈县| 通辽市| 合山市| 滁州市| 华坪县| 漳浦县| 博湖县| 云南省| 平泉县| 南平市|