小程序开发经验多页面数据同步

标签:程序,开发,经验,页面,数据,同步 发布时间:2019年08月20日 点击6

在许多的产品中,都会存在跨页面间必要数据同步,如下示例:

为了更好的理解该场景,我们再细致描绘一下:

  1. 本场景包括4个页面:动态广场小我中间我的动态动态详情
  2. 首先百度优化公司,进入动态广场页,请求加载数据,展示动态列表,其中,我们用绿色内阴影区分该条动态是“我的”,其他未加内阴影的透露表现是“别人的”;
  3. 然后,进入小我中间页,请求加载数据,展示获赞数量;
  4. 点击我的动态,进入我的动态页,请求加载数据,展示我的动态列表;
  5. 点击其中一条动态,进入动态详情页,请求加载数据,进行点赞操作;
  6. 在第5步中,点同意功后,回退到我的动态页,可以看到该条动态点赞状况和数量发生转变,已经同步;
  7. 再回到到小我中间页,也可以看到获赞数量发生转变,已经同步;
  8. 再回到动态广场页,也可以看到对应的一条动态点赞状况和数量发生转变,已经同步;

下面我们来探究一下这个场景的实现,在此之前,我们先要了解在点赞时,该场景中各页面的状况及关系。

如上图所示,当我们在点赞时,4个页面都已经在是打开的(4个webview)。当我们点同意功时,点击左上解返回时,动态详情页的webview关掉,直接看到下一层webview,也就是我的动态页,这个页面是已经存在的。其他页面也是如此。

那对于这些已经存在的页面,我们应该如何同步更新数据呢?

当然,假如比较懒,可以直接在onShow的时候重新拉数据渲染页面。但显然这是特别很是低级、不可取也没需要的做法。重新拉数据必要耗时,页面重新渲染也会看到闪屏,关键是根本没需要重新拉数据,由于数据发生了转变,前端是知道的。

所以我们可以如许做,在动态详情页点同意功时,保存一个数据到全局globalData中去,回到我的动态页,在onShow中去检测全局globalData中是否有点赞转变的数据,有的话,就读掏出往来来往更新响应的动态。

// 动态详情页js
onLike() {
  ...
  success: () => {
    App.globalData.like = {
      fid: 10001,
      likes: 1,
      hasLike: true         
    }
  }
}

// 我的动态页js
onShow() {
  if(App.globalData.like !== null) {
    // 读取globaldata.like数据去更新
    this.doUpdata()
    // 分外必要细致,更新完后,必要把globaldata.like清掉,不然下次onShow还会继承走到该逻辑
    App.globalData.like = null
  }
}
复制代码

如许好像可以达到我们的目的,无请求、纯前端局部更新。

但如许还存在一个题目,当我们再退回到小我中间页时,要检查下获赞数量是否必要更新,以及回到动态广场页时豪沃驾驶室总成,也要检查点赞有没有发生转变。但在这两个页面onShow去判断App.globalData.like时,都已经检测不到了,由于该数据已经在我的动态onShow中置为null了。

概括来说,在点赞时,只生产了一条数据,但有多个消耗者,哪个页面先把数据消耗了,其他页面也就无法检测到数据了

由此,我们想到那就使用EventBus来处理。

首先,我们本身实现一套简单的EventBus。

源码见:git.weixin.qq3564/xinyuanliu/…

在小程序启动时,初始化EventBus:

const Event = require('/util/events.js').default

App({
  events: null,
  onLaunch(options) {
    this.initEvents()
    // doOtherThings
  },
  initEvents() {
    this.events = new Event()
  },
  emitFeedsLike(data) {
    this.events.emit('feedsLike', data)
  },
  emitPublishFeeds(data) {
    this.events.emit('publishFeeds', data)
  },
  ...
}
复制代码

各个页面在onLoad时,注册监听事件(在此以我的动态页为例):

// 我的动态.js
const App = getApp()

Page({
  data: {
    list: []
  },
  onLoad: function (options) {
    ...
    // 监听点赞事件广播
    ↓ 重点在这里 ↓
    App.events.on('feedsLike', data => {
      console.log('我的动态页面收到点赞转变关照:', data)
      // 进行更新操作
    })
    // 监听发布事件广播
    ↓ 重点在这里 ↓
    App.events.on('publishFeeds', data => {
      console.log('我的动态页面收到发布动态关照:', data)
      // 进行更新操作
    })
  },
  ...
})
复制代码

然后在动态点赞时,发出事件关照。(这里一条动态是封装成组件,不属于某一个页面,点赞事件也是封装在组件内)

const App = getApp()

Component({
  properties: {...},
  methods: {
    // 点赞
    tapLike(e) {
      let { likes, hasLike } = this.data

      likes += (hasLike && -1  1)
      hasLike = !hasLike

      this.updateFeeds(likes, hasLike).then(() => {
        this.setData({
          likes,
          hasLike
        })

        // 广播事件
        ↓ 重点在这里 ↓
        App.emitFeedsLike({
          uid: this.data.uid,
          fid: this.data.fid,
          likes,
          hasLike
        })
      })
    },
    ...
  }
})
复制代码

如许,我们便在小程序中实现了一套跨页面数据同步的方案。

直观上这已经特别很是完善的实现了我们的需求。但在小程序中存在一个与我们常规经验不太同等的地方。那就是页面在关掉后,它里面的对象并没有烧毁电锅炉厂,这点是由于小程序的逻辑层是共用一个进程。

因此,每次进入页面,都会注册一次监听事件,而退出页面后河北人事考试中心,该事件并不会烧毁。如许的话,多次重复进入页面,就会注册多个重复事件,当事件发生时,就会实行多次相应。请细心观察下图!

为了避免该征象出现,我们切记要在页面的onUnload事件中,自动烧毁监听事件。
Page({
  eventsListener: {},
  data: {
    list: []
  },
  onLoad: function (options) {
    ...
    // 监听点赞事件广播
    ↓ 重点在这里 ↓
    this.eventsListener.feedsLike = App.events.on('feedsLike', data => {
      console.log('我的动态页面收到点赞转变关照:', data)
      // 进行更新操作
    })
    // 监听发布事件广播
    ↓ 重点在这里 ↓
    this.eventsListener.publishFeeds= App.events.on('publishFeeds', data => {
      console.log('我的动态页面收到发布动态关照:', data)
      // 进行更新操作
    })
  },
  ↓ 重点在这里 ↓
  onUnload() {
    for (let i in this.eventsListener) {
      App.events.remove(i, this.eventsListener[i])
    } 
  },
  ...
})
复制代码

至此,我们在小程序中完善的实现了跨页面/组件、多页面数据同步。

本文研究的demo均可以小程序中体验,项目源码:git.weixin.qq3564/xinyuanliu/

手机网站建设