ホームページ  >  記事  >  WeChat アプレット  >  WeChat アプレットのページ間で通信する方法

WeChat アプレットのページ間で通信する方法

不言
不言オリジナル
2018-06-26 17:06:392806ブラウズ

この記事では主に WeChat アプレット ページ間で通信する 5 つの方法を紹介します。その内容は非常に優れているので、参考として共有したいと思います。

PageModel (ページモデル) はミニプログラムにとって非常に重要な概念です。app.json からも、ミニプログラムがページで構成されていることがわかります。

上に示したように、これは共通の構造を持つ小さなプログラムです。ホームページはダブルタブフレーム PageA と PageB、そしてサブページ pageB と PageC です。

次のシナリオを想定します。ホームページの PageA には浮動小数点数があり、PageA から PageC を開いていくつかの操作を行ってから PageA に戻ると、この浮動小数点数を更新する必要があります。明らかに、これには、PageA が対応するリンケージ変更を行えるように、PageC で操作が実行されるときに PageA に通知する必要があります。

ここでの通知は、専門的に言えば、ページ通信です。いわゆる通信では、次の 2 つの条件が満たされる必要があると u3 は考えています:

  1. 相手のメソッド呼び出しを起動する

  2. 起動したメソッドにデータを転送できる

この記事はプロジェクトの実践に基づいて、ミニ プログラム自体の特性と組み合わせて、ミニ プログラム ページ間のコミュニケーション方法についてのディスカッションと要約を作成します。

通信の分類

は、ページレベル(または表示パス)に応じて、

  1. 兄弟ページ間の通信に分類できます。例えば、複数のタブページ間の通信、PageAとPageB間の通信

  2. PageAがPageCと通信するなど、親パスページが子パスページと通信

  3. 子パスページが親パスページと通信し、 PageCがPageAと通信している場合

通信中に相手のメソッドを起動するタイミングに応じて、

  1. 遅延起動、つまりPageCでの操作を終えて戻ってくるまで待つなどに分けられます。 PageAにアクセスし、PageAのメソッドを呼び出す

  2. すぐにActivate、つまりI PageCでの操作が完了したら、PageCでPageAをアクティブにするメソッドを呼び出します

方法1: onShow/onHide + localStorage

onShow/onHide アクティベーション メソッドを使用して、localStorage 経由でデータを渡します。おおよそのロジックは以下の通りです

// pageA
let isInitSelfShow = true;

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

 onShow() {
  // 页面初始化也会触发onShow,这种情况可能不需要检查通信
  if (isInitSelfShow) return;

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

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

   // 清队上次通信数据
   wx.clearStorageSync('__data');
  }

 },

 onHide() {
  isInitSelfShow = false;
 },

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

メリット: 実装がシンプルでわかりやすい

デメリット: 通信完了後、すぐに通信データを消去しないと問題が発生する可能性があります。さらに、localStorage に依存しているため、localStorage の読み取りと書き込みが失敗し、通信障害が発生する可能性があります

注: onShow はページの初期化時にもトリガーされます

方法 2: onShow/onHide + アプレット globalData

方法 1 と同様に、onShow/onHide アクティベーション メソッドを使用して、アプレット globalData の読み取りと書き込みを通じてデータ転送を完了します

// 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
   });

   // 清队上次通信数据
   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';
 }
});

利点: 実装が簡単で、理解しやすい。 localStorageの読み書きを行わず、メモリを直接操作するため、方法1より高速かつ信頼性が高いです

短所:方法1と同様、globalData汚染に注意

方法3:eventBus(またはPubSub) ) メソッド

このメソッドでは、まず PubSub を実装し、サブスクリプションとパブリッシングによる通信を実現する必要があります。イベントを公開するときは、相手のメソッドをアクティブ化し、パラメーターを渡して、イベントのサブスクリプション メソッドを実行します

/* /plugins/pubsub.js
 * 一个简单的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');
 }
});

短所:バインディングの繰り返しの問題には十分注意してください

方法 4: gloabelData ウォッチャーメソッド

先ほどのメソッドでは、globalData を使用して通信を完了します。現在、データ バインディングは Redux シングル ストアのアイデアと組み合わせることで人気があり、globalData を直接監視する場合、通信するにはデータ値を変更し、水を介して呼び出しをアクティブにするだけで済みます。同時に変更されたデータ値そのものをパラメータデータとして使用できます。

デモンストレーションの便宜上、オープンソース ライブラリ ova がオブジェクト監視ライブラリとして使用されます。興味がある場合は、自分で実装できます。

//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;
 }
});

利点: データ駆動型、単一データソース、デバッグが簡単

欠点: 繰り返し監視の問題は依然として存在しており、それを回避する方法を見つける必要があります

方法 5: を直接呼び出しますハックメソッドによる通信ページ

ページの PageModel を直接キャッシュする 通信する場合、通信するページの PageModel を直接検索すると、通信ページの PageModel のすべてのプロパティとメソッドにアクセスできます。クールすぎるということはありません。このような素晴らしい方法を発見してくれたグループの友人に感謝します。これらすべての PageModel を取得する方法を誰かが必ず尋ねるでしょう。残りは非常に単純です。各ページには onLoad メソッドがあり、これをキャッシュするときに、ページのパスをキーとして使用して検索を容易にします。では、ページのパスを取得するにはどうすればよいでしょうか? 答えは、page__route__ 属性です

// plugin/pages.js 
// 缓存pageModel,一个简要实现
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) {
  // 关键点
  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() {
  // 见证奇迹的时刻
  app.pages.get('pages/a/a').sayHello('hello u3xyz.com');
 }
});

利点: 要するに、コミュニケーション ページに対して何でもできるということです。バインドや購読の必要がないため、重複はありません

欠点: __route__ ハック属性の使用にはいくつかのリスクが伴う可能性があります

上記がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトに注目してください。 !

関連する推奨事項:

WeChat ミニ プログラムのページ ジャンプとパラメーターの受け渡しの概要

WeChat ミニ プログラムのページ ジャンプと値の転送の実装

WeChat ミニ プログラムのページ ジャンプとデータ転送

以上がWeChat アプレットのページ間で通信する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。