微信小程序入口场景的问题整理与相关解决方案
前言
最近一段时间都在做小程序。
虽然是第二次开发小程序,但是上次做小程序已经是一年前的事了,所以最终还是被坑得死去活来。
这次是从零开始开发一个小程序,其实除了一些莫名其妙的兼容性问题,大多数坑点都是在微信小程序的各个入口场景处。
所以这里整理一下微信小程序的各个入口场景,以及从这些入口场景进入小程序会面临的问题以及解决方案。
这里只列出常用的几种场景:
- [简单场景]启动小程序并进入
- [简单场景]退出重进(启动小程序后,退出小程序,再次进入小程序)
- [简单场景]退出重进首页(启动小程序后,退出小程序,通过扫二维码再次进入小程序)
- [复杂场景]启动并进入指定页面(从小程序的分享卡片或者微信发送的通知消息进入小程序)
- [复杂场景]退出重进指定页面(启动小程序后,退出小程序,从小程序的分享卡片或者微信发送的通知消息进入小程序)
启动小程序并进入
微信小程序的入口场景光微信提供的场景值就有几十种,但是绝大多数都可以划分为启动小程序并进入。
这是最常用的一种进入小程序的方式,比如通过搜索进入或者点击最近使用小程序的方式进入,都算是这种类型。
这一场景下,首先我们需要明白发生了什么:
下载小程序 => 启动小程序 onlaunch事件触发 => 加载首页 onload事件触发 => 首页 onshow事件
然后在这个场景下,需要注意以下几个问题:
- 这个场景下一般会涉及到登录。
所谓登录,不一定是要在这个阶段做,但是登录信息的判断这个阶段是一定要做的。
通常前端肯定是要将登录的这些信息存储在小程序的storage里,然后在onlaunch事件中判断是否登录,没登录就跳转到登录页面,登录了就跳转到首页。
这里的登录判断一定要放在onlaunch,而不要放在首页的onload里面,因为小程序启动一定会进入onlaunch,而不一定会进入首页的onload。 - 而登录页面在设计的时候最好要加上一个url参数,传入登录成功后跳转到的页面地址,而不是登录之后始终跳转到首页,后面会讲为什么需要这么做。
- onlaunch阶段是否有发出请求,并在请求完成后进行了页面跳转,或者请求完成设置storage,并在onload页面中使用?
这种情况的出现,会导致在请求时间过长时,首页的onload已经执行了,此时就会出现bug。
对于这个问题,有的人会用定时器去判断是否完成这个操作,但是我的建议是尽量避免在onlaunch中进行这些操作。
如果一定要有,那么最好的方式就是做一个加载页面去承载这些功能。 - 首页数据的初始化,一般是放在onload中执行。当然总是有些特殊的需求是要放在onshow里面的。
关于onload和onshow,最常见的处理区别就在跳转页面时。
当载入首页时,先触发onload,再触发onshow。
此时通过wx.navigateto 的方式跳转到页面a,这个时候首页并没有被关闭,那么从页面a再返回首页时,onload就不会触发,但onshow会触发。
通常在加载数据时,一般会用到onload。
但是如果说页面a更新了数据,然后返回首页时,首页的相关数据也需要更新。
那么初始化数据就不能放在onload里,而需要放在onshow里。
(当然还有一种方式是通过getcurrentpages的方式在页面a中调用首页的方法。但是这里极不推荐这种方式,属于某个页面的事情一定要给这个页面。最好不要将页面间的职责通过这种方式打乱,容易引起代码混乱,不易维护。)
退出重进(启动小程序后,退出小程序,再次进入小程序)
这种场景实际上是对第一种场景的扩展。
而所谓的退出小程序不管你是点右上角的退出按钮还是home键直接切出都算是这类退出。
但是退出后再立即进入小程序的时候,依然会进入你退出小程序时所在的页面,而不会触发onlaunch,也不会触发这个页面的onload,不过onshow是肯定会触发的。
这一场景下,首先我们需要明白发生了什么:
再次进入小程序 => 进入退出小程序时所在页面 触发onshow
在这个场景下,只需要注意onshow中是否有不可重复执行的操作。
例如onshow中会获取用户喜欢吃的食物,加载到页面的列表中,在这种场景下,如果不清空之前的列表或者加个判断的话,就会出现重复数据。
退出重进首页(启动小程序后,退出小程序,通过扫二维码再次进入小程序)
这种场景实际上是对第二种场景的扩展。
我们通常给二维码配置的是一个无参数的小程序首页地址,当我们退出小程序,通过扫二维码再次进入小程序时会进入首页。
这一场景下,首先我们需要明白发生了什么:
再次进入小程序 => 进入退出小程序时所在页面a 不触发onshow => 触发页面a onhide => 触发页面a onunload=> 进入首页 onload => 首页onshow
在这个场景下,除了需要注意第二种场景存在的问题,还需要注意页面a的onhide事件中是否会触发奇怪的操作,例如页面跳转。
启动并进入指定页面(从小程序的分享卡片或者微信发送的通知消息进入小程序)
这块场景常见于邀请他人进入小程序,需要注意的是他们往往被赋予了更多的业务功能,也就往往增大了小程序的实现难度。
这一场景下,首先我们需要明白发生了什么:
下载小程序 => 启动小程序 onlaunch事件触发 => 加载指定页面 onload事件触发 =>指定页面 onshow事件
这里就可以看出,并不是进入小程序就一定会进入首页的onload。
所以这就是为什么之前强调不要将登录判断放在首页的onload中,而一定要放在onlaunch里。
但是这里又和扫二维码不同,扫二维码的链接一般都是指定的首页。
而这里通常跳转到的是非首页的页面,而且可能还多了复杂的业务功能。
我们在需求分析和设计阶段应该更多地考虑到这里可能会引发的复杂问题,而尽量将此处的业务逻辑简化,或者加大估时。
接下来,我们将根据业务从简单到复杂,慢慢讲解这个场景下可能存在的问题。
最简单的邀请函(进入小程序首页)
和第一种场景差不多,这里略过
进阶邀请函(进入小程序指定页面,带参数,需要根据参数初始化页面)
这种情况下,需要考虑以下几个问题:
- 首先在onlaunch阶段会判断是否登录,没登录那么就需要跳转到登录页面,登录页面登录之后,肯定要跳转到这个页面,而不是首页。
所以之前说过登录页面设计的时候需要传入一个url参数,来明确登录成功后跳转到哪个页面。 - 这种跳转到指定页面的情况通常都需要一个回到首页的按钮。
就比如邀请某人查看一篇文章,点击邀请卡片后会进入小程序内的文章详情。
一般在小程序内通常是通过点击文章列表跳转到文章详情,那么这个时候可以逐级返回到首页。
但是在点击邀请函进入的情况是没有返回功能的,此时如果没有回到首页功能,那么用户可能就永远没法回到首页。
(其实是可以的,但是小程序的的这个功能藏得比较深,不要指望所有用户都那么热爱摸索) - 这里一定要特别注意第一种场景的第三个应该注意的问题,对于第一种场景而言那个问题因为启动次数很多容易出现,但是在当前的场景下可能很容易被忽略掉。
涉及身份的邀请函(进入小程序指定页面,带参数,需要根据参数切换身份,更可能涉及到登录)
为了更好地说明这种情况,我们来列举一个场景。
如果有一个打车软件,进入这个软件后有两种身份,一种是乘客,一种是司机。
用户是司机,那么看到的是页面a或者选定了taba,如果是乘客,那么看到的是页面b或者选定了tabb。
而且还有一个需求,用户上次登陆时什么身份,这次登陆也是什么身份。
考虑到换手机的场景,那么这个信息肯定是存储在服务端的,所以进入小程序的时候会去请求服务端进行判断。
现在我用司机的身份发了个单,微信给了个通知消息,我没点开。然后切换到乘客的身份了,再去点击通知消息,那么我会以司机的身份去打开这个消息。
这个场景其实在业务上来看是很合理的,但是对于我们的程序实现来看,复杂度一下子就上来了。
- 首先我们确定一下这个请求身份信息的请求在哪个阶段发出?
onlaunch?
那么是不是需要在onload阶段去获取这个身份的信息然后给出不同的页面?
这样一下子就会出现进阶邀请函的第三个问题,而且还不仅仅是这一个问题,之后我们会讲到。
所以这个地方需要做一个专门的邀请加载页面去处理这个事情。 - 分离出一个单独的加载页面之后,其实我们的工作会变的简单清晰起来。
因为我们只需要去做我们这个页面所需要做的事情就行了。
根据参数去获取我们现在的身份,然后以这种身份跳转到相应的页面。 - 这里还涉及到一个问题,那就是正常启动而不是通过通知消息进入的时候,也需要去请求服务端获取身份信息。
我给的建议是一定要另外单独建一个页面去承载这个功能,而不要将这两个加载页面糅合到一起。
里面的页面展示我们可以用组件化的方式去做,但是页面的逻辑一点更要分开。
因为这两种情况真的很容易混杂,也是为了利于后面的维护工作。 - 正常启动时的加载页面也可以看情况糅合到首页的onload里面。
但是如果有可能,还是希望放在单独的页面里。
首页往往功能很多,代码量比较大,不要将本来可以分离出去的功能放进去。
还是那句话,页面的职责分开。
我这里讲的其实还是一个比较常见的功能,通常我们的业务也不一定像上面这样简单。
所以如果涉及到这方面的操作,在需求分析和设计的时候就应该考虑清楚。
如果等到功能开发的时候再去考虑这些事情,那么等待你的一定是延期或者加班。
退出重进指定页面(启动小程序后,退出小程序,从小程序的分享卡片或者微信发送的通知消息进入小程序)
这种场景同样是第四种场景的进阶,但是如果你在第四种场景中使用了我所说的加载页面,那么接下来的问题会简单很多。
这一场景下,首先我们需要明白发生了什么:
再次进入小程序 => 进入退出小程序时所在页面a 不触发onshow => 触发页面a onhide => 触发页面a onunload => 进入邀请加载页面onload => 加载页面onshow
对于第四种场景中的打车小程序而言,如果按照我们先前所说没有在onlaunch中获取身份信息,而是放在了加载页中,那么现在什么都不用改。
如果获取身份信息的请求放在onlaunch中,现在又得在onload中加一道逻辑。
当然这里还是得注意一个问题,对于这一类型的进入小程序的方式,比如从分享卡片进入和微信的通知消息进入。
即使他们所进入的页面不同,但是他们都可以使用这个载入页面去做判断。
与正常启动场景的载入页面是不同的,他们本来就是同一种入口场景。
所以该共用的地方还是得共用,用不同的业务code判断即可。
总结
总的来说,以上的几种情况应该能涵盖绝大多数小程序的入口场景。
整理的目的其实主要是为了做需求分析和设计时参考使用,以避免在考虑业务问题时漏过这些场景导致后期的工作计划受到影响。
所谓加班和项目延期发布,大都是前期需求分析和设计考虑不周。
我们不可能考虑到所有的场景,但是应该尽善尽美。
谋定而后动,前事不忘后事之师,也算是pdca了。