在小程序里点开一件商品,页面轻巧地滑进详情;看完退回来,列表还停在原来的位置。这一进一退再寻常不过,背后全靠跳转逻辑撑着。跳转做得顺不顺,往往直接决定用户用起来是“跟手”还是“别扭”。
先把原理拆开。一个小程序,本质上是一组页面的集合,每个页面在项目里都有固定的位置,也就是常说的页面路径。所谓跳转,说白了就是告诉框架:别停在这一页了,去把那个路径的页面加载出来。框架为此备好了一整套 API,开发者调用它们,再配上用户的动作——点按钮、滑列表、扫码进入,甚至从一条消息通知里点进来——一次跳转就算完成了。想通这一层再看后面的选择,其实都是在回答同一个问题:跳过去之后,用户还回不回来?

最省事的做法是用 navigator 组件。它像网页里的 a 标签,直接写进 WXML,设好 url,点一下就跳,一行 JS 都不用写。页面简单、交互纯粹时,它是首选。

可真到了实际开发,这么干净的时候不多。跳转前要判断登录态、要拼动态参数,或者得在某个时机由代码主动触发,这时就该 wx.navigateTo 一族 API 出场了。几种方式的差别值得掰开说:navigateTo 会把当前页面压入页面栈,新页面上自带返回按钮,“列表进详情”这种线性流程用它正合适;redirectTo 则是关掉当前页再进新页,栈的深度不变,最典型的场景是登录——登录成功后没必要让用户再“返回”登录页,直接替换掉更合理;navigateBack 主动退栈,还能指定退几层;switchTab 专门伺候底部 tabBar,切 tab 基本只有它能干,因为 tab 页之间不允许用普通方式互跳。
跳转失败时,有一类坑格外冤:页面文件建好了,路径却没在 app.json 的 pages 里注册,点了就是没反应。这种事多半发生在新建页面后忘了同步配置,报错又不直观,排查起来挺磨人。碰到“点了没反应”,先去查注册列表,能省不少力气。
接下来是数据怎么跟着走。URL 参数最直接,路径后面拼 query,新页面在 onLoad 的 options 里取,简单可靠;短处也摆在明处——长度有限、明文可见,中文和特殊字符还得 encodeURIComponent 转一道。数据一多、结构一复杂,就得换路子:挂在 getApp() 上的全局变量,适合放用户信息这类全局状态;本地缓存适合暂存大对象,或者需要跨会话保留的内容;基础库版本够新的话,navigateTo 还支持 eventChannel,两个页面可以互发消息,做“选完收货地址把结果带回来”这类双向交互格外趁手。具体选哪种,看数据的大小、敏感程度和生命周期,不必死守一种。
页面栈管理可能是最容易被忽略、也最容易出事的一环。栈有层数上限,navigateTo 一层一层压下去,叠满十层之后再跳就不生效了。更隐蔽的是逻辑混乱:详情页能回列表,列表又进详情,栈里塞满重复页面,用户按返回键被反复带回同一个界面——这种体验,谁遇上谁烦。解法倒不难:该用 redirectTo 替换的就替换;循环流程记得用 navigateBack 收尾,或者干脆 reLaunch 清空重来;跳转关系最好在动手写代码前先在纸上画清楚,比事后排查划算得多。
说到底,跳转不是孤立的技术点,它划定了整个小程序的动线。路线设计得顺,用户几乎感觉不到页面的存在;设计得乱,每一步都在提醒他“这东西是拼凑出来的”。把这几组 API 的脾气摸清楚,再拿自己的业务把动线亲手走两遍,很多问题在上线之前就能自己撞见。至于更深的玩法,留给实际需求推着去探索,往往比照着教程学来得快。
अभी लॉगिन करें