Home  >  Article  >  WeChat Applet  >  How to communicate between pages in WeChat mini program

How to communicate between pages in WeChat mini program

不言
不言Original
2018-06-26 17:06:392792browse

This article mainly introduces 5 ways to communicate between WeChat applet pages. The content is quite good. I will share it with you now and give it as a reference.

PageModel (page model) is a very important concept for mini programs. You can also see from app.json that mini programs are composed of pages.

As shown above, this is a small program with a common structure: the homepage is a double-Tab frame PageA and PageB, and the sub-pages pageB and PageC.

Let us assume this scenario: PageA on the homepage has a floating number. When we open PageC from PageA, do some operations, and then return to PageA, the floating number needs to be refreshed. Obviously, this requires that PageA be notified when operations are performed in PageC, so that PageA can make corresponding linkage changes.

The notification here, professionally speaking, is page communication. The so-called communication, u3 believes that the following two conditions must be met:

  1. activates a method call of the other party

  2. can pass data to the activated method

Based on the project practice and the characteristics of the mini program itself, this article will discuss and summarize the communication methods between mini program pages.

Communication classification

Can be divided into:

  1. According to the page level (or display path):

  2. Sister pages communication. For example, communication between multiple Tab pages, communication between PageA and PageB

  3. The parent path page communicates with the child path page, such as PageA communicating with PageC

The child path page communicates with the parent path page, such as PageC communicating with PageA

  1. According to the timing of activating the other party's method during communication, it can be divided into:

  2. Delayed activation, that is, after I finish the operation on PageC, I wait to return to PageA and then activate PageA's method call

Activate immediately, that is, after I finish the operation on PageC, I activate PageA on PageC Method call

Method 1: onShow/onHide localStorage

##Use onShow/onHide activation method, Pass data through localStorage. The general logic is as follows

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

Advantages:

Simple implementation and easy to understand

Disadvantages:

If the communication data is not cleared immediately after the communication is completed , problems may occur. In addition, because it relies on localStorage, localStorage may fail to read and write, causing communication failure.

Note: onShow will also be triggered during page initialization
Method 2: onShow/onHide applet globalData

Same as method 1, use the onShow/onHide activation method to complete the data by reading and writing the applet globalData Pass

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

Advantages: Simple implementation and understanding. Because it does not read or write localStorage and directly operates the memory, it is faster and more reliable than method 1.

Disadvantages:Same as method 1, pay attention to globalData pollution
Method 3: eventBus (or PubSub) method

This method requires first implementing a PubSub and achieving communication through subscription and publishing. When publishing an event, activate the other party's method, pass in parameters at the same time, and execute the subscription method of the event

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

Disadvantages: Be very careful about repeated bindings Question
Method 4: gloabelData watcher method

In the aforementioned method, we use globalData to complete communication. Nowadays, data binding is popular. Combined with the idea of ​​redux single store, if we directly watch a globalData, then to communicate, we only need to modify the data value and activate the call through water. The data value modified at the same time can itself be used as parameter data.

For the convenience of demonstration, the open source library oba is used as the object monitoring library. If you are interested, you can implement one yourself.

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

Advantages: Data-driven, single data source, easy to debug

Disadvantages: The problem of duplicate watches still exists, we must find ways to avoid it
Method 5: Directly call the communication page method through the hack method

Cache the page PageModel directly. When communicating, directly find the communication page The PageModel of the page can then access all properties and methods of the PageModel of the communication page. It can't be too cool, thank you to the friends in the group for discovering such an amazing way. Someone will definitely ask, how to get all these PageModels. The rest is very simple. Each page has an onLoad method. In this event, we can cache this (that is, the PageModel of some pages). When caching, use the page path as the key to facilitate search. So how to get the page path? The answer is the attribute 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');
 }
});

###Advantages: ###It is sharp and powerful, and you can do whatever you want to the communication page. There is no need to bind or subscribe, so there is no duplication###

Disadvantages: Using the __route__ hack attribute may have some risks

The above is the entire content of this article, I hope it will be helpful to everyone's learning, For more related content, please pay attention to the PHP Chinese website!

Related recommendations:

Introduction to page jump of WeChat mini program

Page jump of WeChat mini program Implementation of value passing

WeChat applet page jump and data transfer

The above is the detailed content of How to communicate between pages in WeChat mini program. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn