小程序跨页面交互的作用与方法详解
去年年末,微信小程序的分包大小已经到达了12M大小,一方面说明小程序的确逐步为开发者放开更大的权限,另一方面也说明了对于某些小程序8M的大小已经不够用了。我个人今年也是在开发一个toB小程序应用。这里列举一些跨页面交互的场景。
对于B端应用的业务需求来说,小程序开发的复杂度相对比网页开发要复杂一些。一个是双线程的处理机制问题,另一个是页面栈之间交互问题。
注:笔者目前只需要开发微信小程序,为了在小程序页面中可以使用propertiesbehaviorsobservers等新功能,已经使用Component构造器来构造页面。具体可以参考微信小程序Component构造器。如果你也没有多端开发的需求,建议尝试使用,可以得到不错的体验。
性能优化类
对于小程序在页面中点击触发wx.navigateTo跳转其他页面,中间会有一段时间的空白加载期(对于分包出去的页面,空白期则会更长),但是这是小程序内部机制,没有办法进行优化。我们只能眼睁睁的等待这段没有意思的空白期过去。
当考虑到跳转页面后的第一件事情便是取数逻辑,那么我们是否能够进行优化呢?答案是肯定的。我们没有办法直接在当前页面取得数据之后再进行跳转操作(这样操作更不好),但是我们却可以利用缓存当前的请求,详情可以参考我之前的博客文章——Promise对象3种妙用。
代码如下:
constpromiseCache=newMap() exportfunctionsetCachePromise(key,promise){ promiseCache.set(key,promise) } exportfunctiongetCachePromise(key){ //根据key获取当前的数据 constpromise=promiseCache.get(key) //用完删除,目前只做中转用途,也可以添加其他用途 promiseCache.delete(key) returnpromise }
做一份全局的Map,然后利用Map缓存promise对象,在跳转之前代码为:
//导入setCachePromise函数 Component({ methods:{ getBookData(id){ constpromise=//promise请求 setCachePromise(`xxx:${id}`,promise) }, handleBookDetailShow(e){ constid=e.detail this.getBookData(id) wx.navigateTo({url:`xx/xx/x?id=${id}`}) } } })
而跳转之后的代码也如下所示:
//导入getCachePromise函数 Component({ properties:{ id:Number }, lifetimes:{ attached(){ constid=this.data.id //取得全局缓存的promise constbookPromise=getCachePromise(`xxx:${id}`) bookPromise.then((res)=>{ //业务处理 }).catch(error=>{ //错误处理 }) } }, methods:{ getBook(){ //获取数据,以便于错误处理上拉刷新等操作 } } })
如此便可以同时处理取数和页面加载的逻辑,当然,这个对于页面有耦合性,不利于后续的删除与修改。但考虑如果仅仅加在分包跳转之间可能会有不错的效果。
想要无侵入式,可以进一步学习研究微信小程序之提高应用速度小技巧以及wxpage框架,同时考虑到无论是ToC还是ToC用户,都有可能存在硬件以及网络环境等问题,该优化还是非常值得的。
当然微信小程序为了减少冷启动时间,提供了周期性更新数据预拉取功能。
注:上面的promiseCache只作为中转的用途,不作为缓存的用途,如果你考虑添加缓存,可以参考我之前的博客文章——前端api请求缓存方案。
通知类
如果是pc端中进行交互,对于数据的CRUD。例如在详情页面进行了数据的修改和删除,返回列表时候就直接调取之前存储的列表查询条件再次查询即可,而对于移动端这种下拉滚动的设计,就没有办法直接调用之前的查询条件来进行搜索。
如果从列表页面进入详情页面后,在详情页面只会进行添加或者修改操作。然后返回列表页面。此时可以提示用户数据已经进行了修改,请用户自行决定是否进行刷新操作。
如在编辑页面修改了数据:
constapp=getApp() component({ methods:{ asynchandleSave(){ //... app.globalData.xxxChanged=true //... } } })
列表界面:
constapp=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工具的检查):
exportdefaultfunctionmitt(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个方法,onemit以及off。
只要在多个页面导入生成的mitt()函数生成的对象即可(或者直接放入app.globalData中也可)。
Component({ lifetimes:{ attached:function(){ //页面创建时执行 constchangeData=(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请求缓存方案
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。