优化uni-app页面间的传参跳转【兼容多端】

问题场景

options传值的想必用的都比较多,除了option传值的场景外,还有两个场景用的也比较多:

1)传复杂对象

对于传递复杂对象options就有点力不从心了,毕竟URL模式GET传递参数的长度有限。此时需要采用eventChannel模式,而默认的模式使用复杂,需要进行再优化。

2)返回模式

虽然eventChannel也实现了上下级页面(对于页面栈式应用,我称之为上下级比较合适)传递参数,但是灵活度高也就意味着使用复杂。

理想中的模式

之前写过ElementUI的窗体模式封装,参考同样的理念。我需要实现这样更贴近开发逻辑的调用效果:

假设是A->B

A页面传参跳转到新页面:

/**** @param url* @param data 跳转页面请求的数据,由跳转页面在onLoad或onMount调用util.onPageInit(initFunc)接收* @param backFunc 跳转页面返回数据,由backFunc回调接收
export const navigateTo = (url: string,data: Record<string, any> = {},backFunc: (value: any) => void = () => {}
)*/navigateTo('/page/updateOrder?orderId=1111', {signKey: 'XXXXXX'}, (orderDetail) => {console.log(orderDetail)
})

/page/updateOrder是要打开的页面,orderId是URL上能够看到的参数,而signKey是隐藏的签名参数,不便在URL里展示的内容。payDetail对用的是返回的方法,在打开页面里采用goBack(见后面代码)返回时,将修改后的详细构成信息刷新到当前页面。这样好处是按返回不用全局刷新,试想如果是一个下拉列表修改第N页的数据,修改完后返回结果整个列表全部刷新找不到修改的位置了体验该多么的糟糕。

此时新的页面读取orderId直接使用option可以获取,而{signKey}部分,在onMouted或onLoad方法如下获取,B页面调用获取A传递参数的方法:

/*** 页面初始化接收参数的事件,接收由navigateTo传递的复杂对象数据* @param initFunc 接收参数的事件*/onPageInit((data)=>{console.log('post data:', data)
})

B页面处理完毕,返回到A页面的方法:

/*** 返回逻辑,如果小程序或H5是直接进入页面(此时无页面栈),返回时则直接跳转到首页* @param backValue 返回到前一个页面的方法,undefined则不执行返回,如果要执行返回逻辑但不传递参数可以传null或空对象*/goBack({amount: 9999, address: 'ABCD'})

会立即触发跳转回A页面,且返回后,A页面会打印收到的返回值{amount: 9999, address: 'ABCD'}

试想如果你忘记那些uniapp五花八门的传参方案,是不是觉得,这样应该是页面跳转传参本来应该的样子?

实现它

我们约定两个事件:

initData:新窗口接收参数的方法

navBack:从新窗口返回的方法

navigateTo代码如下:

/**** @param url* @param data 跳转页面请求的数据,由跳转页面在onLoad或onMount调用util.onPageInit(initFunc)接收* @param backFunc 跳转页面返回数据,由backFunc回调接收*/
export const navigateTo = (url: string,data: Record<string, any> = {},backFunc: (value: any) => void = () => {}
) => {// 简化跳转,可以在template直接用uni.navigateTo({url,events: {// 这个是添加到跳转前页面的on事件navBack: backFunc},success: (result: UniNamespace.NavigateToSuccessOptions) => {result.eventChannel.emit('initData', data)}})
}

initFunc接收参数的方法如下:

/*** 页面初始化接收参数的事件,接收由navigateTo传递的复杂对象数据* @param initFunc 接收参数的事件*/
export const onPageInit = (initFunc: (data: any) => void) => {const instance = getCurrentInstance()if (!instance) {console.error('you must call it in onLoad() or onMounted() method')} else {;(instance.proxy as any).getOpenerEventChannel().on('initData', (data) => {initFunc(data)})}
}

goBack返回前一页面数据的方法如下:

/*** 返回逻辑,如果小程序或H5是直接进入页面(此时无页面栈),返回时则直接跳转到首页* @param backValue 返回到前一个页面的方法,undefined则不执行返回,如果要执行返回逻辑但不传递参数可以传null或空对象*/
export const goBack = (backValue?: any) => {// 返回逻辑修正版,如果小程序或H5直接进入页面(此时无页面栈),返回时直接跳转到首页const pages = getCurrentPages()const eventChannel: UniNamespace.EventChannel = (pages[pages.length - 1] as any).$vm.getOpenerEventChannel()if (pages && pages.length > 0) {const firstPage = pages[0]if (pages.length === 1 && (!firstPage.route || firstPage.route !== Global.HOME_ROUNTE)) {// 栈底页非首页,去首页uni.reLaunch({url: Global.HOME_ROUNTE})} else {uni.navigateBack({success: () => {if (backValue !== undefined) {eventChannel.emit('navBack', backValue)}}})}} else {// 无栈底页,去首页uni.reLaunch({url: Global.HOME_ROUNTE})}
}

Global.HOME_ROUNTE是首页地址,由常量文件定义

就这点代码,剩下的没了,如果硬是要再讲点什么的话。说一下eventChannel的原理:

eventChannel在每个页面实现了一个事件总线。在navigateTo时,跳转成功的success里会带上成功页面的eventChannel,这样我们则可以给跳转后的页面发送数据。而currentInstance(this)的getOpenerEventChannel()则是获得打开它的页面的事件总线。向其emit发送数据,则发送到前一个页面。

如果不使用cuurentInstance,uni-app里我们还可以采用如下底层方法获得每个页面的event总线

        const pages = getCurrentPages()const topPage = pages[pages.length - 1] // 当前页面(栈顶)const eventChannel: UniNamespace.EventChannel = (topPage as any).$vm.getOpenerEventChannel()

然后同样可以进行emit、on等操作来注册和发送事件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/52430.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在多云生态下,如何实现跨云的自动化身份管理?

在多云环境下实现跨云的自动化身份管理是一个重要的课题&#xff0c;因为这可以帮助企业确保用户和应用程序能够在不同云服务提供商之间无缝地访问资源&#xff0c;同时保持高度的安全性和合规性。以下是一些关键技术和实践方法&#xff0c;用于实现跨云环境下的自动化身份管理…

Linux驱动开发基础(中断)

所学来自百问网 目录 1. 嵌入式中断系统 2. 中断处理流程 3. 异常向量表 4. Linux系统对中断的处理 4.1 ARM 处理器程序运行的过程 4.2 保护现场 5. Linux 系统对中断处理的演进 5.1 硬件中断和软件中断 5.2 中断拆分(上半部和下半部) 5.2.1 tasklet 5.2.2 工作队列…

git笔记:git常用命令备忘录

1、工作区域和文件状态 1.1、工作区域 git的数据管理分为四个区域&#xff1a; 工作区&#xff08;Working Directory&#xff09; 本地工作目录&#xff0c;是我们电脑上的目录&#xff0c;是我们实际编写代码的区域&#xff0c;修改完工作区的文件后可以使用git add命令将…

72 华为资源库

1 报文格式 https://info.support.huawei.com/info-finder/tool/zh/enterprise/packetformat 2 华为IP网络电子书 资源可以下载 https://e.huawei.com/cn/topic/enterprise-network/ip-ebook 3 华为产品文档 https://support.huawei.com/enterprise/zh/doc/index.html 4 华为…

【HuggingFace Transformers】BertSelfOutput 和 BertOutput源码解析

BertSelfOutput 和 BertOutput源码解析 1. 介绍1.1 共同点(1) 残差连接 (Residual Connection)(2) 层归一化 (Layer Normalization)(3) Dropout(4) 线性变换 (Linear Transformation) 1.2 不同点(1) 处理的输入类型(2) 线性变换的作用(3) 输入的特征大小 2. 源码解析2.1 BertSe…

Facebook的AI助手:如何提升用户社交体验的智能化

在现代社交媒体平台中&#xff0c;人工智能&#xff08;AI&#xff09;的应用正逐渐改变人们的社交体验。Facebook作为全球最大的社交媒体平台之一&#xff0c;已在AI技术的开发与应用上投入了大量资源&#xff0c;并通过其AI助手为用户提供了更加个性化、智能化的互动体验。这…

vagrant 创建虚拟机

创建一个名为 “Vagrantfile” 的文件&#xff0c;修改如下内容&#xff1a; Vagrant.configure("2") do |config|(1..3).each do |i|config.vm.define "k8s-node#{i}" do |node|# 设置虚拟机的Boxnode.vm.box "centos/7"# 设置虚拟机的主机名…

逆向中的游戏-入土为安的第二十五天

逆向中的游戏 CE的介绍 Cheat Engine &#xff0c;简称CE&#xff0c;是逆向工程师常用的几大神器之一&#xff0c;也是游戏汉化、破解以及外挂编写中常用的工具&#xff0c;其功能包括&#xff1a;内存扫描、十六进制编辑器、调试工具&#xff0c;可以进行反汇编调试、断点跟…

代码随想录算法训练营_day28

题目信息 122. 买卖股票的最佳时机 II 题目链接: https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/题目描述: 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你…

Springboot-RequestContextHolder

RequestContextHolder 是 Spring 框架中的一个类,主要用于在多线程环境中存储和访问 HTTP 请 求的上下文信息。它允许在 Spring 应用程序中从任何位置访问当前请求的相关信息,比如 HTTP 头部、会话数据等,而无需将请求对象直接传递到每个方法中。 主要用途 存储请求上下…

Seata 学习

简介 我们都知道 Seata 是一个分布式事务的解决方案&#xff0c;今天我们就来带大家了解一下什么是分布式事务&#xff0c;首先我们先来了解一下基础的知识——事务&#xff0c;我们先来了解一下事务的概念是什么。 基本概念 事务四部分构成— ACID&#xff1a; A(Atomic)&…

小程序路由传参和获取页面栈方法

路由方法 navigateTo, redirectTo 只能打开非 tabBar 页面。switchTab 只能打开 tabBar 页面。reLaunch 可以打开任意页面。页面底部的 tabBar 由页面决定&#xff0c;即只要是定义为 tabBar 的页面&#xff0c;底部都有 tabBar。调用页面路由带的参数可以在目标页面的onLoad中…

matlab 计算复共轭

目录 一、概述1、算法概述2、主要函数二、代码示例1、求复数的复共轭2、求矩阵中复数值的复共轭三、参考链接本文由CSDN点云侠翻译,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的抄袭狗。 一、概述 1、算法概述 2、主要函数 Zc = conj(Z)返回 Z …

【python】Python中小巧的异步web框架Sanic快速上手实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

理解torch.argmax() ,我是错误的

torch.max() import torch# 定义张量 b b torch.tensor([[1, 3, 5, 7],[2, 4, 6, 8],[11, 12, 13, 17]])# 使用 torch.max() 找到最大值 max_indices torch.max(b, dim0)print(max_indices) 输出&#xff1a;>>> print(max_indices) torch.return_types.max( valu…

【13.3 python中的高级文件操作】

python中的高级文件操作 在Python中&#xff0c;除了基本的文件读写和目录操作外&#xff0c;还有一些高级的文件和目录操作&#xff0c;如删除文件、重命名文件和目录、以及获取文件的基本信息等。这些操作通常通过os模块和pathlib模块来实现。下面我将详细介绍这些操作&#…

Git在IDEA中的集成操作(附步骤图)

1.先做适配操作&#xff0c;将安装的Git软件关联到IDEA中 点击Test之后若成功会显示出Git版本&#xff1a; 2.创建版本仓库 3.创建新的版本 3.1将文件提交到暂存区(不重要) 第一种方式&#xff1a;菜单栏提交 第二种方式&#xff1a;项目右键提交 4.查看历史版本信息 目…

整合sentinel遇到的小问题

1.运行jar包 &#xff0c;端口为默认8080 正确命令 java -Dserver.port8090 -Dcsp.sentinel.dashboard.server127.0.0.1:8090 -Dproject.namesentinel-dashboard -jar sentinel-dashboard-1.8.6.jar -D这些指令要在 -jar前面 在宝塔部署时&#xff0c;直接复制到运行命令后…

acl2的安装和vescmul的运行

使用sat一类的求解器验证乘法器&#xff0c;通常无法收敛&#xff0c;Mertcan Temel博士基于acl2实现了数字电路中乘法器的验证。下面简单介绍一下acl2的安装、vescmul的运行。 1.下载acl2 git clone https://github.com/acl2/acl2.git 2.acl2基于lisp编程语言实现&#xff…

Sparse Kernel Canonical Correlation Analysis

论文链接&#xff1a;https://arxiv.org/pdf/1701.04207 看这篇论文终于看懂核函数了。。谢谢作者