小程序跨页面交互的作用与方法详解

去年年末,微信小程序的分包大小已经到达了 12M 大小,一方面说明小程序的确逐步为开发者放开更大的权限,另一方面也说明了对于某些小程序 8M 的大小已经不够用了。我个人今年也是在开发一个 to B 小程序应用。这里列举一些跨页面交互的场景。

对于 B 端应用的业务需求来说,小程序开发的复杂度相对比网页开发要复杂一些。一个是双线程的处理机制问题,另一个是页面栈之间交互问题。

注: 笔者目前只需要开发微信小程序,为了在小程序页面中可以使用 properties behaviors observers 等新功能,已经使用 Component 构造器来构造页面。具体可以参考微信小程序 Component 构造器。如果你也没有多端开发的需求,建议尝试使用,可以得到不错的体验。

性能优化类

对于小程序在页面中点击触发 wx.navigateTo 跳转其他页面,中间会有一段时间的空白加载期(对于分包出去的页面,空白期则会更长),但是这是小程序内部机制,没有办法进行优化。我们只能眼睁睁的等待这段没有意思的空白期过去。

当考虑到跳转页面后的第一件事情便是取数逻辑,那么我们是否能够进行优化呢?答案是肯定的。我们没有办法直接在当前页面取得数据之后再进行跳转操作(这样操作更不好),但是我们却可以利用缓存当前的请求,详情可以参考我之前的博客文章 ——Promise对象 3 种妙用

代码如下:

const promiseCache = new Map()

export function setCachePromise(key, promise) {
 promiseCache.set(key, promise)
}

export function getCachePromise(key) {
 // 根据key获取当前的数据
 const promise = promiseCache.get(key)
 // 用完删除,目前只做中转用途,也可以添加其他用途
 promiseCache.delete(key)
 return promise
}

做一份全局的 Map,然后利用 Map 缓存 promise 对象,在跳转之前代码为:

// 导入 setCachePromise 函数

Component({
 methods: {
 getBookData(id) {
  const promise = // promise 请求
  setCachePromise(`xxx:${id}`, promise)
 },
 handleBookDetailShow(e) {
  const id = e.detail
  this.getBookData(id)
  wx.navigateTo({url: `xx/xx/x?id=${id}`})
 }
 }
})

而跳转之后的代码也如下所示:

// 导入 getCachePromise 函数

Component({
 properties: {
  id: Number
 },
 lifetimes: {
  attached () {
  const id = this.data.id
  // 取得全局缓存的promise
  const bookPromise = getCachePromise(`xxx:${id}`)
  bookPromise.then((res) => {
   // 业务处理
  }).catch(error => {
   // 错误处理
  })
  }
 },
 methods: {
  getBook() {
  // 获取数据,以便于 错误处理 上拉刷新 等操作
  }
 }
})

如此便可以同时处理取数和页面加载的逻辑,当然,这个对于页面有耦合性,不利于后续的删除与修改。但考虑如果仅仅加在分包跳转之间可能会有不错的效果。

想要无侵入式,可以进一步学习研究 微信小程序之提高应用速度小技巧 以及 wxpage框架,同时考虑到无论是 ToC 还是 ToC 用户,都有可能存在硬件以及网络环境等问题,该优化还是非常值得的。

当然微信小程序为了减少冷启动时间,提供了周期性更新 数据预拉取 功能。

注: 上面的 promiseCache 只作为中转的用途,不作为缓存的用途,如果你考虑添加缓存,可以参考我之前的博客文章—— 前端 api 请求缓存方案

通知类

如果是 pc 端中进行交互,对于数据的 CRUD。例如在详情页面进行了数据的修改和删除,返回列表时候就直接调取之前存储的列表查询条件再次查询即可,而对于移动端这种下拉滚动的设计,就没有办法直接调用之前的查询条件来进行搜索。

如果从列表页面进入详情页面后,在详情页面只会进行添加或者修改操作。然后返回列表页面。此时可以提示用户数据已经进行了修改,请用户自行决定是否进行刷新操作。

如在编辑页面修改了数据:

const app = getApp()

component({
 methods: {
 async handleSave() {
  //...
  app.globalData.xxxChanged = true
  //...
 }
 }
})

列表界面:

const app = getApp()

component({
 pageLifetimes: {
 show() {
  this.confirmThenRefresh()
 }
 },
 methods: {
 confirmThenRefresh() {
  // 检查 globalData,如果当前没有进行修改,直接返回
  if(!app.globalData.xxxChanged) return
  wx.showModal({
  // ...
  complete: () => {
   // 无论确认刷新与否,都把数据置为 false
   app.globalData.xxxChanged = false
  }
  })
 }
 }
})

当然了,我们也可以利用 wx.setStorage 或者 getCurrentPage 获取前面的页面 setData 来进行数据通知,以便用户进行页面刷新。

订阅发布类

如果仅仅只涉及到修改数据的前提下,我们可以选择让用户进行刷新操作,但是如果针对于删除操作而言,如果用户选择不进行刷新,然后用户又不小心点击到了已经被删除的数据,就会发生错误。所以如果有删除的需求,我们最好在返回列表页面前就进行列表的修改,以免造成错误。

mitt

github 上有很多的 pub/sub 开源库,如果没有什么特定的需求,找到代码量最少的就是 mitt 这个库了,作者是喜欢开发微型库的 developit大佬,著名的 preact也是出于这位大佬之手。 这里就不做过多的介绍,非常简单。大家可能都能看明白,代码如下(除去 flow 工具的检查):

export default function mitt(all) {
 all = all || Object.create(null);

 return {
 on(type, handler) {
  (all[type] || (all[type] = [])).push(handler);
 },

 off(type, handler) {
  if (all[type]) {
  all[type].splice(all[type].indexOf(handler) >>> 0, 1);
  }
 },
 emit(type, evt) {
  (all[type] || []).slice().map((handler) => { handler(evt); });
  (all['*'] || []).slice().map((handler) => { handler(type, evt); });
 }
 };
}

仅仅只有3个方法,on emit以及 off。

只要在多个页面导入 生成的 mitt() 函数生成的对象即可(或者直接放入 app.globalData 中也可)。

Component({
 lifetimes: {
 attached: function() {
  // 页面创建时执行
  const changeData = (type, data) => {
  // 处理传递过来的类型与数据
  }
  this._changed = changeData
  bus.on('xxxchanged', this._changed)
 },
 detached: function() {
  // 页面销毁时执行
  bus.off('xxxchanged', this._changed)
 }
 }
})

这里mitt可以有多个页面进行绑定事件,如果需求仅仅只涉及到两个页面之间,我们就可以使用 wx.navigateTo 中的 EventChannel (页面间事件信息通道)。可以参考微信小程序wx.navigateTo方法里的events参数使用详情及场景,该方案的利好在于,传递到下一个页面的参数也可以通过 EventChannel 来通知,以便于解决 properties 传递数据不宜过大的问题。

注: 一个页面展示很多信息的时候,会造成小程序页面的卡顿以及白屏。小程序官方也有长列表组件 recycle-view。有需求的情况下可以自行研究,这个不在这里详述。

鼓励一下

如果你觉得这篇文章不错,希望可以给与我一些鼓励,在我的 github 博客下帮忙 star 一下。
博客地址

参考文档

微信小程序 Component 构造器

微信小程序之提高应用速度小技巧

wxpage

mitt

Promise对象 3 种妙用

前端 api 请求缓存方案

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 微信小程序跨页面数据传递事件响应实现过程解析

    这篇文章主要介绍了微信小程序跨页面数据传递事件响应实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在实际工作中有很多场景需要在第二个页面中将用户操作之后的将数据回传到上一页面.接下来将我的方案分享给小伙伴. 本次示例采用 uni-app 框架和 weui 样式库 实现思路 创建一个 Emitter,用于事件处理 创建一个 ... 在实际工作中有很多场景需要在第二个页面中将用户操作之后的将数据回传到上一页面.接下来将我的方案分享给小伙

  • 详解小程序中h5页面onShow实现及跨页面通信方案

    小程序webview的现状 h5页面在小程序中的交互(跳转)场景 h5跳转小程序native页面(如:调用小程序地址选择能力,然后返回对应的地址信息给h5页面) h5跳转己方业务线的h5页面(内部页面交互,方式比较多样) h5跳转其它业务线的h5页面(如:交易流程,相关页面可能有其他业务线提供) 主要痛点 在完成相关操作后, 页面状态需要更新 ,目前常见的更新方式有如下两种: 第一种:通过url传参(如:url中加入__isonshowrefresh=1,告诉webview再次onshow时候刷

  • 微信小程序跨页面传递data数据方法解析

    这篇文章主要介绍了微信小程序跨页面传递data数据方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Q:小程序怎么把页面data里的数据传到另外的页面? 或者小程序怎么吧表单里的数据传到另外的页面? A:1.可以使用url传递数据. 例如在A页面中传递数据,需要注意的是,wx.switchTab中的url不能传参数. wx.navigateTo({ url:'../pageB/pageB?name=raymond&gender=male'

  • 小程序跨页面交互的作用与方法详解

    去年年末,微信小程序的分包大小已经到达了 12M 大小,一方面说明小程序的确逐步为开发者放开更大的权限,另一方面也说明了对于某些小程序 8M 的大小已经不够用了.我个人今年也是在开发一个 to B 小程序应用.这里列举一些跨页面交互的场景. 对于 B 端应用的业务需求来说,小程序开发的复杂度相对比网页开发要复杂一些.一个是双线程的处理机制问题,另一个是页面栈之间交互问题. 注: 笔者目前只需要开发微信小程序,为了在小程序页面中可以使用 properties behaviors observers

  • 微信小程序实现页面导航与传参功能详解

    目录 一.页面导航 概述 分类 声明式导航 导航到tabBar页面 导航到非tabBar页面 后退导航 编程式导航 导航到tabBar页面 导航到非tabBar页面 后退导航 导航传参 声明式导航传参 编程式导航传参 一.页面导航 概述 顾名思义,页面导航指的是页面之间的相互跳转, 而页面传参就是在加载页面时将特定的参数传递过去从而成为该页面的参数. 分类 声明式导航:在页面上声明一个<navigator>导航组件,通过点击该组件实现页面跳转 编程式导航:通过调用小程序专门的导航API,实现页

  • 微信小程序全屏滚动字幕的实现方法详解

    目录 一.实现背景 二.实现代码 三.滚动速度 四.后续优化 实现效果 一.实现背景 无意中在某音上看到用手机横屏作为广告屏的视频,大部分都是用第三方软件实现的: 以及在汽车后挡风玻璃放置提醒字样的视频,这种基本是要花钱买屏幕,通过手机控制屏幕内容: 遂想实现这种效果 二.实现代码 1,滚动字幕 zimu.wxml,界面布局,很简单,没啥特别的,顶部一个返回按钮,为了不影响整体效果,可以把这个按钮做成透明的图片放上去:除了那个按钮剩下的就是滚动的字幕组件了 <!--pages/zimu/zimu

  • 微信小程序整合使用富文本编辑器的方法详解

    本文实例讲述了微信小程序整合使用富文本编辑器的方法.分享给大家供大家参考,具体如下: 使用WxParse插件实现小程序的富文本显示 ,下载地址:富文本插件WxParse 具体使用步骤: 1. 复制插件文件夹到项目根目录,emojis是表情包,可选择性删除 2. 在.js文件中引入WxParse模块 var WxParse= require('../../../wxParse/wxParse.js'); 3. 在.wxss文件中引入WxParse.wxss样式,也可以在app.wxss中引入 @i

  • 小程序获取用户信息的两种方法详解(getUserProfile和头像昵称填写)

    目录 第一种使用 getUserProfile 第二种使用 头像昵称填写 总结 相信大家之前也经常使用open-data获取用户的头像和昵称吧,但微信的这个改编意味着我们要使用新的方法获取信息了.在讨论区引发了很大的讨论,接下来我们一起尝试两种获取信息的方法. 第一种使用 getUserProfile 我们可以查看一下官方文档 wx.getUserProfile(Object object),获取用户信息.页面产生点击事件(例如 button 上 bindtap 的回调中)后才可调用,每次请求都

  • 让微信小程序支持ES6中Promise特性的方法详解

    遇到的问题 微信开发者工具更新版本后, 移除了开发者工具对 ES6 中 Promise 特性原生的支持, 理由是因为实体机器是不支持 Promise 的, 所以我们需要引入第三方的 Promise 库 微信更新日志 解决方案 下载第三方库 在这里我引入的是 Bluebird 库, 可以到Bluebird官网 下载需要的文件,也可以通过本地下载 Bluebrid 提供了两种已经构建好的完整的 Promise 库文件, 未经压缩的 bluebird.js 和已压缩的 bluebird.min.js

  • 微信小程序当前时间时段选择器插件使用方法详解

    本文实例为大家分享了微信小程序当前时间时段选择器的实现代码,供大家参考,具体内容如下 DEMO效果图 插件思路 准备工作 获取当前时间,同时获取当前的年.月.日.周几: 创建处理日期数字的函数: 创建格式化日期的函数: 创建获取某月天数的函数: 创建获取季度开始的月份函数. 获取时段 创建获取当天的时段函数: 创建获取本周的时段函数: 创建获取本月的时段函数: 创建获取本季度的时段函数: 创建获取本年的时段函数: 创建自定义时段函数. 准备阶段的JS constructor() { this.n

  • 微信小程序3种位置API的使用方法详解

    获取位置 获取当前的地理位置.速度.当用户离开小程序后,此接口无法调用:当用户点击"显示在聊天顶部"时,此接口可继续调用. wx.getLocation(object) <view class="container"> <button bindtap='getLocation'>获取位置</button> <view wx:if="{{latitude !=''}}"> <view>纬度

  • 微信小程序swiper轮播图组件使用方法详解

    本文实例为大家分享了微信小程序swiper轮播图组件的使用,供大家参考,具体内容如下 在components中新建文件夹swiper components/swiper/swiper.wxml <!--components/swiper/swiper.wxml--> <view class="container">     <swiper class="swiper-box" bind:change="swiperChange

随机推荐