文章目录
- 往期回顾
- 页面通讯
- 出现场景
- 通讯方案
- 通讯方案小结
- 如何父传子
- 页面跳转时序图
- uni.\$on和eventChannel.on使用推荐
往期回顾
uniapp 踩坑记录 uni.$on为什么不能修改data里面的数据
页面通讯
出现场景
我们在一个页面往另一个页面跳转的时候,希望跳转的页面的参数是动态生成的,可以复用的。比如我们在逛淘宝的时候,我们点击一个商品,进去就是商品的详情页。商品和商品详情页的对应关系就需要商业页面给商品详情页面传递商品的信息参数
而且有时候我们甚至希望能传递多个通讯信息。这样跳转的页面就可以提供更加差异化的复制功能。
通讯方案
序号 | 通讯方法 | 方法名 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|---|
1 | 页面缓存 | uni.setStorage(OBJECT) uni.getStorage(OBJECT) | 全局缓存,下次打开依然存在,存取方便,官方自带同步异步缓存方法 | 不适合页面通讯,使用频次低的缓存。因为数量多了不好管理 | 全局的动态变量,例如用户名,用户等级,用户权限等 |
2 | Vue全局变量 | vue.prototype.key= | 一次设置,全局使用 | 同页面缓存 | 封装好的方法 |
3 | 路由通讯 | uni.navigateTo(OBJECT) | 通过跳转的在url里面添加?key=value设置变量,在onLoad里面取出变量。使用方便 | 需要自己将对象转化为url对应参数,而且对象深度只能为一层,url长度有限制 | 跳转页面传递简单变量 |
4 | 页面通讯 | uni.$emit(eventName,OBJECT) uni.$on(eventName,callback) | 使用key进行通讯,可以多次通讯而不是打包一起通讯,方便业务迭代 | key值管理问题,会和全局通讯,容易误触发其它页面 | 全局通讯,页面通讯 |
5 | 通道通讯,事件通讯 | EventChannel.emit(string eventName, any args) | 在路由跳转的success里面实现通讯 | 只能1对1页面通讯,不能全局通讯 | 跳转页面通讯 |
通讯方案小结
通讯总体分类 | 通讯方法序号 | 通讯特点 |
---|---|---|
直接通讯 | 3,4,5 | 直接页面传值通讯,适用于局部通讯和页面唤醒 |
间接通讯 | 1,2 | 通过修改和读取全局变量,适合全局静态变量 |
uni.$emit和EventChannel.$emit的区别
uni.$emit | EventChannel.$emit | |
---|---|---|
父传子 | 在success里面回调 | 在success里面回调 |
子传父 | 任意位置 | 在event里面回调 |
作用域 | 全局,直到被销毁 | 局部,页面销毁即结束 |
声明 | 简洁 | 稍微有点复杂 |
使用注意 | 如果是uni.on注册的监听器需要页面退出时销毁 | 无需注意 |
如何父传子
父传子我看了很久,才从官方文档里面找到父传子的方法。
页面跳转时序图
以为触发器需要在声明之后才能触发,所以我们需要在回调函数里面触发
实际代码
//A页面
uni.navigateTo({url: url,success(res) {console.log('回调函数')uni.$emit('test',{ value:'页面通讯测试' })//页面通讯res.eventChannel.emit('test_data', {value:'通道通讯测试'})//通道通讯}
})//B页面onLoad() {console.log('页面跳转成功')uni.$once('test',res=>{console.log('通讯成功!')console.log(res)})const eventChannel =this.getOpenerEventChannel()eventChannel.on('test_data',res=>{console.log(res)})
}
uni.$on和eventChannel.on使用推荐
两者使用起来其实差不多,都可以达到父传子,子传父的作用。但是因为作用域的原因,evenetChannel在不同页面的变量可以重名,eventChannel更适合父传子,uni.$on适合子传父