Hello, I’m Skinner and this is my seventh post

sequence

This paper deals with the transmission of data from child or grandchild to parent, bottom-up

I believe that we usually in the small program development must have encountered data communication between the page or components, the small program data communication are what? How to choose the right method of communication? This is the focus of this article.

Relations division

Before we discuss the different data communication modes, let’s define the relationships between applets and components. I summed it up, which can be roughly divided into the following three categories:

  1. Father and son
  2. brotherhood
  3. Ye sun relationship

In different relationships, which can be pages or components between different roles, we will reveal how data communication takes place one by one.

Father and son

There are two main situations in the father-son relationship:

  1. The parent is the page and the child is the component
  2. The parent is a component and the child is a component

This relationship is probably the most frequent occurrence, after all, most applets are small and beautiful, and may not be too detailed. In this case, we can complete the data communication by listening for events triggered by the child component in the parent page.

Methods a

<! <component-tag-name bindmyevent= <component-tag-name bindmyevent= <component-tag-name bindmyevent="onMyEvent"/ > <! --> <button bindtap="onTap"</button> Component({methods: {)onTap() {const myEventDetail = {} // detail object, provided to the event listener function const myEventOption = {} // the option to trigger the event this.triggerEvent('myevent', myEventDetail, myEventOption)
    }
  }
})
Copy the code

brotherhood

Fraternal relationships also fall into two categories:

  1. Brothers are pages
  2. Brothers are components

Brothers are pages

This relationship refers to pages at the same level, which is basically A jump between pages, so how does page B change the data of page A when you jump from page A to page B?

Method 2

The onShow/’ onHide ‘method is used to retrieve data from onShow and store data from onShow, using localStorage or globalData as a data transfer method.

<! --app.js--> App({ globalData: { count: 0 }, }); <! Page - A - - >onShow() {let countValue = wx.getStorageSync('count'); <! --globalData's approach -->letcountValue = getApp().globalData.count; <! ---->if(countValue){ this.setData({ count:countValue }) } <! --> getApp().globaldata.count = null <! -- -- -- -- >}onHide(){
    wx.removeStorageSync('count')}, <! - page B -- -- >onShow() {<! --> getApp().globaldata.count = 1 <! ----> wx.setStorageSync('count', 1); }Copy the code

Ye sun relationship

Parent-grandson relationship is the most complex data communication, because it is not a direct transmission, if it is monitored through method one, it needs to pass the event through multiple levels, if the node is deep, it can be imagined that the code is difficult to understand and maintain.

We can create a global event stack EventBus, using this EventBus to subscribe to publish events, that is, we often use the publish subscription model, that in the small program how to implement?

Methods three

<! -- Step 1: Implement an event stack class --> class EventBus {constructor() { this.bus = {}; } // on subscribe to on(type, fun) {
        if(typeof fun ! = ='function') {
            console.error('fun is not a function');
            return;
        }
        (this.bus[type] = this.bus[type] || []).push(fun); } // emit emit(type. param) {let cache = this.bus[type];
        if(! cache)return;
        for (letevent of cache) { event.call(this, ... param); }} // off release off(type, fun) {
        let events = this.bus[type];
        if(! events)return;
        let i = 0,
            n = events.length;
        for (i; i < n; i++) {
            let event = events[i];
            if (fun === event) {
                events.splice(i, 1);
                break; } } } } module.exports = EventBus; <! -- Step 2: Introduce --> import EventBus from in app.js'./common/event-bus/index.js'; App({ eventBus: new EventBus(), }); <! Step 3: listen for an event in the parent page or component --> onLoad:function(options) {
    app.eventBus.on('add-count', this.addCount);
}
onUnload: function(options) {
    app.eventBus.off('add-count', this.addCount); } <! Trigger events in child components --> methods: {addCount() {
        app.eventBus.emit('add-count'); }}Copy the code

In addition, there is another way, we can cache the page pageModel object in each page onLoad cycle, and then get the page object in the grandchild component, thus triggering the corresponding method of the grandchild page object.

Methods four

<! Class pageModel {class pageModel {class pageModel {constructor() {
        this.pageCache = {};
    }

    add(page) {
        let pagePath = this._getPageModelPath(page);
        this.pageCache[pagePath] = page;
    }

    get(path) {
        returnthis.pageCache[path]; } delete(page) { delete this.pageCache[this._getPageModelPath(page)]; } <! -- This code is the key, stores the __route__ attribute --> _getPageModelPath(page) {returnpage.__route__; }}exportdefault PageModel ; <! -- Step 2: import PageModel from app.js'./common/page-model/index.js'; App({ pageModel: new PageModel(), }); <! Caches the page in the onLoad cycle --> onLoad:function(options) { app.pageModel.add(this); } <! -- Step 4: Descendants get grandparents --> methods: {addCount() {
        app.pageModel.get('pages/communicate/index').addCount(); }}Copy the code

conclusion

First, methods three and four can be used in all situations, but they need to be used on a case-by-case basis. If the page level is not deep, a simple event listener (method 1) can be used. There is no need to create a total stack of events, because if the number of pages is large, various listeners can easily duplicate names through EventBus, resulting in some unknown situations. In addition, method 4 also has a certain risk, in case the wechat base library does not store the page object in __route__, our method will not work.

All sample code can be viewed in the following two ways, if you like my article, please go to 👍 to encourage oh, thank you!

Preview in developer tools

Check it out on Github