小程序提供了 navigator组件 及功能相对应的 API 用于页面导航,不同的导航操作形成不同的页面栈信息,详细见官网文档路由的说明,但是官方文档不推荐也没有提供修改页面栈的API。
导航方式
open-type="navigate" 或 api: wx.navigateTo
open-type="redirect" 或 api: wx.redirectTo
open-type="switchTab" 或 api: wx.switchTab
open-type="reLaunch" 或 api: wx.reLaunch
open-type="navigateBack" 或 api: wx.navigateBack
页面栈形态
- navigate 和 redirect 的区别:前者在页面栈保留跳转前页面,再将跳转后的页面推入页面栈,可以通过 navigateBack 返回页面栈前面的页面,delta可设置返回的层数;后者不保留跳转前页面,将其出栈,而后跳转后页面入栈,此时若用 navigateBack,返回的是页面栈里保存的其他页面,如果没有其他页面,则仍在此页面;用符号语言表示为:
navigate:A -> B 其页面栈依次为:A - ABredirect: A -> B 其页面栈依次为:A - B
看几个例子,都是在实际项目开发中抽象出来的:
- A navigateTo-> B navigateBack(1)-> A 页面栈为:A-AB-A
- A navigateTo-> B navigateTo-> C navigateBack(2)-> A 页面栈为:A-AB-ABC-A
- A redirectTo-> B navigateBack-> B(栈内无其他页面) 页面栈为:A-B-B
- A navigateTo-> B redirectTo-> C navigateBack-> A 页面栈为:A-AB-AC-A
- A navigateTo-> B redirectTo-> A navigateTo-> C redirectTo-> A navigateTo-> D redirectTo-> A navigateTo-> E redirectTo-> A navigateTo->(无效了,因为此时页面栈已到达限制:5) 页面栈为:A-AB-AA-AAC-AAA-AAAD-AAAA-AAAAE-AAAAA
- R redirectTo-> B/C/D/E redirectTo-> A 页面栈为:E- B/C/D/E-A
小结
- 在能够形成相对独立闭环的页面间方才使用
navigate
导航,这样可以保证每个页面可以单独分享而不影响页面导航关系,比如某表单页面-选择省份城市-回到表单页面,这种类型就是一个闭环,其中,省份城市选择的页面不会被单独访问。 - 在各自独立的页面间用
redirect
导航,比如这种需求:首页有去其他各个模块的入口,每个模块都有返回首页的按钮,而这些模块的入口不只是首页,也有其他,如登录成功后直接进入某模块页面,在公众号菜单有分别进入各个模块的入口,这种情况下,每个模块虽然与首页之间有父子关系,但却不适合用navigate 和 navigateBack
导航。 - 2017-05-25补充:发现一篇文章《小程序基础篇之页面路由》, 对于页面栈形态给了图解,看起来更直观
页面导航逻辑 - 某项目
- 各功能页返回首页方式看情况判断:若从首页进入则navigateBack返回首页;若是直接打开功能页的,则redirect打开首页;
- 绑定与否过滤控制页面访问权限:已绑定直接访问,未绑定redirect到绑定页面,绑定成功后自动回到原进入的页面;(该小程序功能需绑定对应数据方可使用)
- 微信授权判断:未授权或已失效重新发起授权,授权成功后刷新原页面;授权流程见小程序文档(下方有个授权流程图)
- 用户拒绝授权:弹框引导其重新打开授权;(打开设置API:
wx.openSetting: success (res.authSetting['scope.userInfo'])
)
- 前提:保存打开小程序的初始路径,作为以上各种情况页面跳转依据;打开app的路径可在app启动关于显示的时候获取,具体见文档:框架-逻辑层-注册程序
app: onLaunch/onShow(options.path)
更新:小程序授权规则有更改,直接查看其文档,此处附上一实际项目中使用的授权流程:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。