主体: 企业支付宝小程序 、 个人支付宝小程序
采用不同的路由 api 跳转,可能会有不同的限制,也会带来不同的影响。 下面将对这些内容做详细介绍,请开发者提前了解,以在使用场景中选择恰当的路由 api 进行跳转
url 详解
url 是需要跳转的目标页面路径及参数。需要将路径配置在app.json
的pages
中(注:若目标路径为/pages/pageb/index?key=value
,则只需配置pages/pageb/index
即可)。下面我们从目标页面角度看看这几种路由方式有什么区别。
注:表格中的 tabbar 页面是指在 app.json 的 tabbar 字段定义的页面
路由 api | 可跳转到 tabbar 页面 | 可跳转到非 tabbar 页面 | url 后是否可带参数 |
---|---|---|---|
my.navigateto | ✕ | ✓ | ✓ |
my.redirectto | ✕ | ✓ | ✓ |
my.relaunch | ✓ | ✓ | ✓ |
my.switchtab | ✓ | ✕ | ✕ |
url 格式
url 支持 绝对路径 和 相对路径。
如果是 '/'
开头或者插件地址,视为绝对路径。否则视为相对路径,并根据当前页面路径计算得到绝对路径。
假设pages
文件夹下有两个并列页面pagea/index
和pageb/index
,则从 a 页面跳转到 b 页面时:
// 使用绝对路径
{url : '/pages/pageb/index'}
// 使用相对路径
{url : '../pageb/index'}
注意:若 url 为'pages/pageb/index'
,则相当于相对路径'./pages/pageb/index'
,那最后计算出的绝对路径实则为/pages/pagea/pages/pageb/index
。所以如果开发者想使用绝对路径,别忘了加开头的'/'
。
url 携带参数
除了 my.switchtab 路径后不能带参数,其他三种路由 api 都是可以带参数的。
参数与路径之间使用?
分隔,参数键与参数值用=
相连,不同参数用&
分隔。
// 参数的传递与接收,以 navigateto 为例
// a 页面
my.navigateto({
url: '/pages/pageb/index?key1=value1&key2=value2',
})
// b 页面
onload(query) {
console.log(query); // {key1: value1, key2: value2}
},
url 参数中有特殊字符
小程序在收到 url 携带的参数时,会用&
分割出每一个参数,再用=
分割出参数值。
但如果我的参数值中就包含=
或&
这种特殊字符呢?eg:
const value = 'va&lu=e';
my.navigateto({
url: `/pages/pageb/index?key=${value}`,
});
以上案例中,我们的本意是只有一个键值对的,但最终的跳转路径为/pages/pageb/index?key=va&lu=e
,参数会被解析成两个键值对。这样就产生了歧义。
另外,还有一些字符,如%
等。当 url 参数中含有这些字符时,可能会引起解析程序的歧义,从而造成页面无法加载等异常情况。
那么,在小程序中,有哪些方案可以解决 url 参数中含有特殊字符的情况?
方案一:可先对 url 中的参数进行 encode,再进行跳转
const url = `/pages/pageb/index?key=${encodeuricomponent('%%value')}`;
my.navigateto({
url,
});
方案二:也可以在app.json
中增加如下配置
"behavior": {
"decodequery": "disable" // 设置为disable后,基础库不再对全局/页面参数的键/值做encodeuricomponent
},
路由与页面
页面栈
小程序以栈的形式维护当前的所有页面。可通过 getcurrentpages() 获取当前页面栈的数据,将页面栈的数据以数组的形式返回。第一个元素为凯发k8官方网娱乐官方首页,最后一个元素为当前页面。下面我们从页面栈角度看看这几种路由方式有什么区别。
路由方式 | 页面栈表现 | 页面栈深度变化 |
---|---|---|
my.navigateto | 新页面入栈。 | 加 1 |
my.redirectto | 当前页面出栈,新页面入栈。 | 不变 |
my.relaunch | 页面全部出栈,新页面入栈。 | 1 |
my.switchtab | 页面全部出栈,新页面入栈。 | 1 |
my.navigateback | 当前页面出栈。 | 减 1 |
页面间的通信
当使用my.navigateto()
从 pagea 跳转到 pageb 时,页面之间可通过 eventchannel 进行页面间的通信。eg:
// pagea
my.navigateto({
url: '/pages/pageb/index?id=1',
events: {
// a 页面 接收 b 页面传过来的数据。
pageb_data(data) {
console.log(data); // { "message": "hello~ 我是 pageb" }
},
},
success: function(res) {
// a 页面向 b 页面 传值
res.eventchannel.emit('pagea_data', { data: 'hi~ 我是 pagea' })
}
})
// pageb
page({
onload() {
const eventchannel = this.getopenereventchannel();
// b 页面 接收 a 页面传过来的数据。
eventchannel.on('pagea_data', data => {
console.log(data); // { "data": "hi~ 我是 pagea" }
});
// b 页面向 a 页面 传值
eventchannel.emit('pageb_data', {
message: 'hello~ 我是 pageb',
});
},
});
上述案例中,pagea 和 pageb 都是通过 eventchannel.emit 发送数据的。需要注意的是,b 页面是通过 eventchannel.on 接收 a 页面传过来的值,而 a 页面是在my.navigateto()
的入参events
中,定义了一个方法名与eventchannel.emit
中事件名称相同的方法,从而监听到 b 页面传过来的值。 注:
若想实现跨页面通信,可参考评论中的实现案例
页面切换的监听
- 通过
onback()
可监听返回按钮的点击。 - 通过
onload()
可监听页面初始化。当有新页面入栈,即使用my.navigateto()
、my.redirectto()
、my.relaunch()
、my.switchtab()
跳转到目标页面时,目标页面会触发此监听方法。 - 通过
onshow()
可监听页面的显示。此方法不仅能监听新页面入栈。当在 页面 b 使用my.navigateback()
或点击返回按钮回到 a 页面时,会在 a 页面触发此监听方法。 - 通过
onunload()
可监听页面的销毁。使用my.navigateback()
,或使用my.redirectto()
、my.relaunch()
、my.switchtab()
跳转到目标页面时,那些出栈的页面都会触发此监听方法。 - 通过
onhide()
可监听页面的离开。此方法不仅能监听到页面的销毁,当 页面 a 使用my.navigateto()
跳转到 页面 b 时,a 页面也会触发此监听方法。
小程序页面 与 h5 页面的相互跳转
小程序页面跳转到 h5 页面
pagea 是小程序页面,pageb 是用web-view
组件承载的 h5 页面
// 从 pagea 跳转到 pageb,并携带参数
my.navigateto({
url: '/pages/pageb/index?id=1&key2=value2',
})
// pageb 中的 .axml 文件
h5 页面拿到小程序页面传过来的参数
function getdata(key, url) {
var str = url;
str = str.substring(1, str.length);
var arr = str.split("?");
var obj = new object();
for (var i = 0; i < arr.length; i ) {
var tmparr = arr[i].split("=");
obj[decodeuricomponent(tmparr[0])] = decodeuricomponent(tmparr[1]);
}
return obj[key];
}
var url = window.location.search;
var id = getdata('id', url);
h5 页面跳转到小程序页面
在 h5 页面中引入https://appx/web-view.min.js
,h5 就可以使用路由相关的接口了。详情请见 web-view h5 页面承载
路由对导航栏、tabbar 的影响
导航栏“返回凯发k8官方网娱乐官方首页”按钮
“返回凯发k8官方网娱乐官方首页” 按钮展示规则:当页面为最底层页面(页面栈深度为 1 ),且页面为非凯发k8官方网娱乐官方首页、非 tabbar 页面时,导航栏左上角默认展示 “返回凯发k8官方网娱乐官方首页” 按钮。
根据规则可知,以下两种情况会展示“返回凯发k8官方网娱乐官方首页” 按钮:
- 当使用
my.relaunch()
,跳转到非凯发k8官方网娱乐官方首页、非 tabbar 页面时,会展示“返回凯发k8官方网娱乐官方首页” 按钮; - 当页面栈深度为 1 时,使用
my.redirectto()
,跳转到非凯发k8官方网娱乐官方首页、非 tabbar 页面,会展示“返回凯发k8官方网娱乐官方首页” 按钮;
导航栏“返回”按钮
“返回”按钮展示规则:当页面栈深度大于 1 时,默认展示“返回”按钮。
根据规则可知,以下两种情况会展示“返回” 按钮:
- 当使用
my.navigateto()
跳转时,会展示“返回”按钮; - 当页面栈深度大于 1 时,使用
my.redirectto()
跳转,会展示“返回”按钮;
底部 tabbar 的展示
使用my.relaunch()
和my.switchtab()
跳转到 tabbar 页面,才会展示底部的 tabbar。所以,请不要用my.navigateto()
或my.redirectto()
跳转到 tabbar 页面。