- 需求的场景描述(希望解决的问题)
需要监听页面路由的变换。在路由变化时做响应的处理
- 希望提供routeChange的相关hook,并可以利用hook的返回值,决定真正路由方向
例如(支持promise更好):
wx.onRouteBeforeChange(({ current: {path: '', query: ''}, next: {},}) => {})
wx.onRouteAfterChange(({ current, next }) => {})
框架类型 | 问题类型 | API/组件名称 | 终端类型 | 微信版本 | 基础库版本 |
---|---|---|---|---|---|
小程序 | 需求 | wx.onRouteChange | 客户端 | 6.0.0 | 2.0.0 |
4 个回答
这个业务侧有需求的话应该是可以自己实现的
请指教
如果你指在需要的地方(比如page.onLoad, page.onShow, page.onHide, component.attached component.detached等生命周期中)通过 getCurrentPages方法读取路由栈信息,那这就太显得太low了。
我需要再每个页面都写这么一段逻辑,即使只有一行封装好的函数,那也需要每个页面都要写一次。
由于小程序并没有路由表注册功能(url竟然用文件路径这么强耦合的方式),我们希望建立路由表来管理和控制路由的跳转,这基本不算是业务侧的需求,更像是一个lib。因此对于路由hook的需求是很强烈的。
如果你使用 Component 构造器构造页面,那你可以使用 behavior 来给所有页面施加一组统一的逻辑。
不过,路由控制逻辑应该在路由方法真正实施前执行,才具有比较好的体验。因而封装 wx.navigateTo 是更加合理的方法。
原则上我们在基础库内仅提供基础特性和对性能有价值的特性,不提供高层封装。
首先,路由跳转不仅仅是在component中,page也会有。Page构造器的功能明显弱于Component构造器。但Page构造器是不能省略的,毕竟小程序无法实现SPA页面应用。小程序的路由体系决定了必须要使用多页面应用。因此behavior功能在Page构造器中无能为力。
其次,没有要拦截并抑制路由跳转的意图。我所做的事情也是要封装wx.navigateTo等方法达到小程序基础库没有提供的更友好的API。没有要求小程序提供高层封装,只是希望暴露更多的基础接口出来,比如,路由变化的事件,wx.onRouteChange能感知路由的变化。如果能提供before,after的hook是极好的。至少能提供wx.onRouteBack是最基础的吧,因为页面的回退可以不受代码控制(点击左上角 < 图标),这使得路由变化无法感知,因此,想封装高阶接口代理小程序基础的路由功能就无法完成,因为,只能感知路由前进(navigatoTo,redirectTo都需要写代码完成,没有其他方式),无法感知路由后退,就无法形成逻辑闭环,即无法维护完整的路由栈信息。想做更友好更高阶的路由功能成了不可完成的事情。
感觉官方人员应该多看看当下主流的框架(如VUE),看看当下流行框架强大而丰富的路由功能,借鉴借鉴经验。没有要求小程序官方提供高级特性,但至少应该提供基础特性供开发者自行封装和迭代吧。
如果你不知道使用 Component 构造器构造页面,请点击左边的蓝色字。
如果没有拦截(或改变)的意图,我们有个即将开放的接口仅用于“读取”(目前正在处理一些 edge case,之后会新增)。
小程序的基础架构、设计目标和基础库更新方式与常见框架并不一样,所以很多高层接口也不一样,请理解。
考虑了一下,有了个大胆的想法
其实我觉得在现有功能上是基本可以实现路由监听的。那就是重写Page方法, 比如:
const _oldPage = Page;
const pages = [];
Page = functin(option) {
const onLoad = option.onLoad;
const onUnload = option.onUnload;
option.onLoad =
function
(initOption) {
if
(pages[pages.length - 1] !==
this
) {
pages.push(
this
);
}
typeof
this
.beforeRouteEnter ===
'function'
&&
this
.beforeRouteEnter();
onLoad.call(this, initOption);
};
option.onUnload =
function
() {
pages.pop();
typeof
this
.beforeRouteLeave ===
'function'
&&
this
.beforeRouteLeave();
onUnload.call(this);
}
option.router = {
navigateTo:
function
({ url}) {
typeof
this
.beforeRouteLeave ===
'function'
&&
this
.beforeRouteLeave();
wx.navigateTo({ url: url });
},
// 同理类似编写switchTab, navigateBack等方法,只是注意其路由变化时触发函数不要重复触发, 因为使用某些路由跳转方法会卸载页面,触发一次onUnload方法
};
_oldPage(option);
};
向上面这样,在每个页面逻辑里面强行插入自定义的路由状态变更逻辑。应该可以优化很多路由方面的问题
只是一些特性啊,效率上可能没有那么高,比如beforeRouteLeave中无法传入下一个页面实例,如法阻止网页跳转。
有错误欢迎指正。
如果不考虑默认导航(顶部和底部的导航)的点击的话,可以简单对几个跳转方法做个封装的嘛
由于没有hook对于路由回退(点击左上角的<图标)无法感知,因此无法维护完整的路由信息。只支持push , replace的路由是不完整的路由功能,也不能正常使用。
路由回退后不能及时修改路由栈信息,就不能使用相对路径的路由功能,如果只使用绝对路径的路由,那在小程序路由的基础上再维护一套路由栈信息就没有那么重要了。只是把url从具体文件路径用一组自定义的字符串代替,可以认为是消除magic strings而已。并不是完备的路由管理。
关键字:
路由事件监听,路由事件钩子,路由事件,路由钩子,
小程序路由事件监听,小程序路由事件钩子,小程序路由事件,小程序路由钩子