前言
只要你的小程序超过一个页面那么可能会需要涉及到页面参数的传递,下面我总结了 4 种页面方法。
路径传递
通过在url后面拼接参数,参数与路径之间使用 ? 分隔,参数键与参数值用 = 相连,不同参数用 & 分隔;如 ‘path?key=value&key2=value2’。
案例:A页面带参数跳转到B页面
A页面跳转代码
goB(){
wx.navigateTo({
url: '/pages/B/index?id=value',
})
},
B页面接收代码
onLoad: function (options) {
console.log('id', options.id)
}
上面的案例是字符串参数,但是很多情况下需要传递对象,如下方代码。
Page({
data: {
userInfo:{
name:'cym',
age:16
}
},
goB(){
wx.navigateTo({
url: '/pages/B/index?id='+this.data.userInfo,
})
},
})
如果使用上面同样的方式结构,输出的结果是:[object Object]
这个时候需要先把对象通过JSON.stringify(obj)将 object 对象转换为 JSON 字符串进行参数传递,再到接收页面通过JSON.parse解析使用。
A页面跳转代码
goB(){
let userStr = JSON.stringify(this.data.userInfo)
wx.navigateTo({
url: '/pages/B/index?id='+userStr,
})
}
B页面接收代码
onLoad: function (options) {
console.log('id', JSON.parse(options.id))
}
全局变量
通过App全局对象存放全局变量。
app.js代码
App({
// 存放对象的全局变量
globalData:{},
})
A页面跳转代码
// 获取App对象
const app = getApp()
Page({
/**
* 页面的初始数据
*/
data: {
userInfo: {
name: 'cym',
age: 16
}
},
goB() {
app.globalData.userInfo = this.data.userInfo
wx.navigateTo({
url: '/pages/B/index',
})
},
})
B页面接收代码
// 获取全局对象
const app = getApp()
Page({
onLoad: function (options) {
console.log(app.globalData.userInfo)
}
})
存放在 App 全局变量里面,可以被多个页面使用,直接从 App 对象获取即可。这个数据是保持在内测中,每次小程序销毁就没有了。
数据缓存
通过存储到数据缓存中。
A页面跳转代码
goB() {
wx.setStorageSync('userInfo', this.data.userInfo)
wx.navigateTo({
url: '/pages/B/index',
})
}
B页面接收代码
onLoad: function (options) {
let userInfo = wx.getStorageSync('userInfo', this.data.userInfo)
console.log(userInfo)
}
存放在数据缓存里面,可以被多个页面使用,直接用 getStorageSync 获取即可。这个数据是保持在数据缓存中,除非清楚数据缓存或者删除小程序否则一直存在。
事件通信
通过事件通信通道。
A页面跳转代码
goB() {
wx.navigateTo({
url: '/pages/B/index',
success:(res)=>{
// 发送一个事件
res.eventChannel.emit('toB',{ userInfo: this.data.userInfo })
}
})
}
B页面接收代码
onLoad: function (options) {
// 获取所有打开的EventChannel事件
const eventChannel = this.getOpenerEventChannel();
// 监听 index页面定义的 toB 事件
eventChannel.on('toB', (res) => {
console.log(res.userInfo)
})
}
总结
大家可以针对具体业务场景来进行选择合适自己的传参方式。
如果options传递的字符串对象过长可能会被截断,可用encodeURIComponent处理一下。
全局可以定义一个Map挂载到wx上,
pageA
wx.$map.set('key', 'value');
pageB
value = wx.$map.pop('key');
事件通讯的方式应该是最符合程序逻辑的。
他可以直接触发对方的函数,双方都可以通讯,这点就类似于PC软件,模态/宿主窗口通讯了。
像全局数据区和硬盘存储区传递数据都是静态数据,无法通知,B页面还可以在onload里面处理,但如果B朝宿主A传数据/事件,A就只能通过onshow强制扫描数据,无法区分B发来的多种信号。
还有一个通讯方式是页面栈,AB都可以通过页面栈访问对方页面,然后直接访问数据调用函数。原理上跟事件通讯差不多.
谢谢宇明老师! 讲的非常棒!
这个方法我试了貌似有问题,清除缓存后,第一次跳转到B页面获取不到数据,第二次就能获取到,onLoad执行的时候数据还没有获取到缓存数据,这是什么原因,有大佬指点一下吗?
请问这个你自己亲自测试过吗?
请问eventChannel是只能在路由跳转的时候的时候使用吗,要实现在app.js里面发出一个事件,然后在页面内接收这个事件然后进行相应的操作有没有什么办法
学到了 社区大佬真多
再加个 navigator 组件哈哈哈哈