uni-app x 页面栈管理指南:getCurrentPages() 与 UniPage 对象的完整解析
2026/9/20 11:10:41 网站建设 项目流程

uni-app x 页面栈管理指南:getCurrentPages() 与 UniPage 对象的完整解析

【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app

在 uni-app x 中,getCurrentPages()是获取当前页面栈实例的核心 API:它以数组形式按栈的顺序返回页面实例,第一个元素为首页,最后一个元素为当前页面。自 HBuilderX 4.31 起,该 API 的返回值升级为UniPage对象数组,开发者可以借此动态读取/修改页面样式(pageStyle)、获取页面原生视图与安全区信息、甚至管理 dialogPage 子弹窗页面栈。本文将结合当前仓库的官方文档与 hello uni-app x 示例工程源码,系统讲解页面栈模型、UniPage 的完整能力、两种 API 风格下的取页面写法,以及基于仓库自动化测试可以验证的实战用法。

getCurrentPages() 与页面栈模型

getCurrentPages()函数用于获取当前页面栈的实例,返回值是一个数组,数组中的元素为页面实例,第一个元素是首页,最后一个元素是当前页面

const pages = getCurrentPages() // pages[0] -> 首页 // pages[pages.length - 1] -> 当前页面

在 uni-app x 中,页面栈是一个先进后出的结构:uni.navigateTo压入新页面、uni.navigateBack弹出页面、uni.switchTab切换 tab 页。通过遍历返回值,可以拿到整个路由链路。

需要特别注意的是:

  • getCurrentPages()获取的是主页面栈,不能直接获取 dialogPage 页面;
  • 拿到主页面UniPage对象后,可以通过getDialogPages()方法获取这个主页面的子弹窗页面栈(dialogPage 栈),详见下文「dialogPage 与主页面栈的关系」;
  • 选项式 vue 中通过this.$page是另一种快速获取当前页面对象的方式,它得到的不是一个页面数组,而是一个具体的当前页面,且同时支持主页面与 dialogPage。

兼容性

| Web | 微信小程序 | Android | iOS | iOS(VDOM) UTS 插件 | HarmonyOS | | :- | :- | :- | :- | :- | :- | | 4.0 | 4.41 | 3.9 | 4.11 | 4.31 | 4.61 |

从兼容性表格可以看出:Web、微信小程序、Android、iOS、HarmonyOS 均有完整支持,其中getCurrentPages()返回UniPage对象数组的能力(UniPage 强化)自 HBuilderX 4.31 起在各端逐步就位。

返回值

| 类型 | | :- | | Array<UniPage> |

getCurrentPages()返回的是UniPage对象数组。每个页面是一个UniPage对象,这个对象上有较多方法,比如获取/修改 pageStyle、获取页面高宽与安全区等,完整说明见 UniPage 文档。

UniPage 对象:页面能力的统一入口

在 uni-app x 中,每个页面都对应一个UniPage对象。通过它既可以读取/修改页面的 pageStyle(让 pages.json 中的静态页面配置可以动态修改),也可以继续获取原生页面对象(如 Android 的View、iOS 的UIView),还可以通过vm属性拿到页面的 vue 实例。

UniPage 在 App 与 Web 平台较完善,在小程序端受小程序平台开放度限制,很多能力无法实现,具体以 UniPage 属性兼容性表 为准。

核心属性

| 名称 | 类型 | 兼容性 | 描述 | | :- | :- | :- | :- | | route | string | Web 4.31 / Android 4.31 / iOS 4.31 / HarmonyOS 4.61 | 页面的路由地址 | | options | UTSJSONObject | Web 4.31 / Android 4.31 / iOS 4.31 | 页面的路由参数信息 | | vm | VueComponent | Web 4.31 / Android 4.31 / iOS 4.31 / HarmonyOS 4.61 | UniPage 的 vue 实例对象 | | pageBody | UniPageBody | Web 4.51 / Android 4.51 / iOS 4.51 / HarmonyOS 4.61 | 页面可使用区域信息,单位为 px | | safeAreaInsets | UniSafeAreaInsets | Web 4.51 / Android 4.51 / iOS 4.51 / HarmonyOS 4.61 | 页面安全区域插入位置(与屏幕边界的距离)信息 | | fullscreenElement | UniElement | Android 4.61 / iOS 4.61 / HarmonyOS 4.61 | 已经进入全屏状态的元素 | | width / height | number | Web 4.63 / Android 4.61 / HarmonyOS 4.63 | 页面窗口宽度 / 高度 | | statusBarHeight | number | Web 4.63 / Android 4.61 / HarmonyOS 4.63 | 页面状态栏高度 | |$vm| VueComponent | 已废弃 | 旧版 vue 实例入口,建议改用vm|

其中pageBody(left/right/top/bottom/width/height,均为 number)描述了页面内容可使用区域;safeAreaInsets(left/right/top/bottom)描述页面安全区域与屏幕边界的距离,二者均从 Android/iOS 4.51 起支持。

vm 属性与 $page

vm是页面 vue 实例对象,其属性包括$data$props$attrs$slots$refs$parent$root$options$el(类型为 UniElement)以及$page(类型为 UniPage)。也就是说,在页面内this.$page(选项式)或getCurrentInstance()?.proxy?.$page(组合式)拿到的正是当前页面的UniPage实例。

提示:4.31 前仅 Web 与 iOS(非 uts 插件)端支持通过page.$vm获取 vue 实例;4.31+ 仅 iOS uts 插件环境不支持通过page.vm获取 vue 实例。

直接获取当前页面的 UniPage

HBuilderX 4.32 起,新增了两种直接获取当前页面UniPage实例的快捷方式,无需再手动从数组末尾取值:

// 选项式 API const curPage = this.$page // 组合式 API const currentInstance = getCurrentInstance() const curPage = currentInstance?.proxy?.$page

这种写法得到的不是页面数组,而是一个具体的当前页面对象;它既适用于主页面,也适用于 dialogPage。仓库中的 get-current-pages.uvue 示例对$pagegetCurrentPages()的等价性做了校验:

const check$page = () : boolean => { const pages = getCurrentPages() const page = pages[pages.length - 1] const $page = currentInstance?.proxy?.$page const res = $page === page console.log('check $page', res) uni.showToast(res ? { title: 'check success' } : { title: 'check fail', icon: 'error' }) return res }

如果$pagegetCurrentPages()栈顶元素严格相等(===),说明二者指向同一UniPage实例。配套的 component-check-page.uvue 还演示了在组件内通过getCurrentInstance()同样可以拿到所属页面的$page

dialogPage 与主页面栈的关系

dialogPage 是 HBuilderX 4.31+ 新增的「背景透明页面」,用于制作能覆盖 pages.json 导航栏和 tabBar 的弹框与内置界面(uni.showModaluni.showActionSheetuni.showLoading等底层均由此实现)。它与主页面(parentPage)的核心区别在于:

  • dialogPage 需要挂在某个主页面上,且不进入主页面栈、不影响路由地址,因此getCurrentPages()不能直接获取 dialogPage;
  • 若想获取 dialogPage,需要先拿到其所属主页面(parentPage)的UniPage,再调用getDialogPages()获取挂载在该主页面上的所有 dialogPage 集合;
  • dialogPage 在 Android 上不是独立 activity,而是与主页面共用同一个 activity 的全屏 view。
// 获取当前主页面的 UniPage const pages = getCurrentPages() const currentPage = pages[pages.length - 1] // 获取该主页面挂载的所有 dialogPage const dialogPages = currentPage.getDialogPages()

getDialogPages()返回Array<UniPage>,兼容性为 Web 4.31 / Android 4.31 / iOS 4.31 / HarmonyOS 4.61,微信小程序不支持(x)。与之配套的getParentPage(): UniPage | null则用于 dialogPage 反向获取所属父页面。dialogPage 的完整机制(uni.openDialogPage/uni.closeDialogPage、生命周期、蒙层处理等)见 dialogPage 文档。

UniPage 的核心方法

除属性外,UniPage提供了一组面向页面管理的实例方法,按用途可分为以下几类。

页面样式:getPageStyle / setPageStyle

getPageStyle(): UTSJSONObject获取当前页面样式,setPageStyle(style: UTSJSONObject): void动态设置页面样式。pages.json 中的pagestyle节点内容可通过这两个 API 读取与修改,但要注意:

  • getPageStyle()获取的是UniPage 上最终生效的值,不是 pages.json 里的原始配置;
  • pages.json 里的内容是静态的,setPageStyle可以动态设置,但并非所有页面样式都支持动态配置
  • 4.31 起,$getPageStyle/$setPageStyle已废弃(仅为向下兼容保留),不再需要前缀$
  • 使用选项式 API 时,不可创建routeoptions同名响应式变量,否则会覆盖当前 page 实例的同名属性。

示例(组合式 + uts):

const getPageStyle = () : UTSJSONObject => { const pages: UniPage[] = getCurrentPages() const currentPage = pages[pages.length - 1] return currentPage.getPageStyle() } const setPageStyle = (style : UTSJSONObject) => { const pages = getCurrentPages() const currentPage = pages[pages.length - 1] currentPage.setPageStyle(style) }

可动态配置的 PageStyle 属性(来自 unipage.md,注意并非所有 pages.json 的 pageStyle 都可以动态修改):

| 属性 | 类型 | Android | iOS | HarmonyOS | web | 默认值 | | :- | :- | :- | :- | :- | :- | :- | | enablePullDownRefresh | Boolean | 4.13 | 4.13 | 4.61 | 4.13 | false | | backgroundColorContent | String | 4.15 | 4.15 | 4.61 | 4.18 | #ffffff | | navigationBarBackgroundColor | String | 4.18 | 4.18 | 4.61 | 4.18 | #007AFF | | navigationBarTextStyle | String | 4.18 | 4.18 | 4.61 | 4.18 | white | | navigationBarTitleText | String | 4.18 | 4.18 | 4.61 | 4.18 | "" | | navigationStyle | String | x | x | 4.61 | 4.18 | default | | backgroundColor | String | 4.18 | 4.18 | 4.61 | x | #ffffff | | backgroundTextStyle | String | 4.31 | 4.31 | x | x | dark | | onReachBottomDistance | Number | x | x | 4.61 | 4.18 | 50 | | pageOrientation | String | 4.18 | 4.25 | x | x | auto | | disableSwipeBack | Boolean | x | 4.18 | x | x | false | | hideStatusBar | Boolean | 4.31 | x | x | x | false | | hideBottomNavigationIndicator | Boolean | 4.31 | x | x | x | false |

注意事项

  • web 端会自动摇树优化未使用的特性,如果整个项目从未使用过下拉刷新enablePullDownRefresh,下拉刷新功能会被摇掉,此时动态开启将无效;
  • app-android 平台的页面是 activity,不支持将backgroundColorContent设为透明;
  • 4.15 版本前,app-ios 平台在 pages.json 中将enablePullDownRefresh设为false时无法通过setPageStyle动态开启,新版已修复。

仓库中的 page-style.uts 定义了可供示例页遍历渲染的PageStyleArray,枚举了可动态配置的键与其可选值,例如navigationBarBackgroundColor(#007AFF / #FFFFFF / #000000)、navigationBarTextStyle(white / black)、navigationStyle(default / custom)、enablePullDownRefresh(true / false)、onReachBottomDistance(50 / 100)、pageOrientation(auto / portrait / landscape)、Android 三键导航相关(androidThreeButtonNavigationTranslucentandroidThreeButtonNavigationBackgroundColorandroidThreeButtonNavigationStyle)等,可直接作为可动态修改属性的权威清单参考。

针对「动态开关下拉刷新」这一典型场景,仓库提供了独立的演示页 set-page-style-disable-pull-down-refresh.uvue:

function setPageStyle(enable : boolean) { // 目前仅支持 enablePullDownRefresh const pages = getCurrentPages(); const currentPage = pages[pages.length - 1]; currentPage.setPageStyle({ enablePullDownRefresh: enable }); data.enablePullDownRefreshStatus = enable }

原生视图与 Activity:getAndroidView / getAndroidActivity / getIOSView / getHTMLElement

| 方法 | 返回类型 | 兼容性 | 描述 | | :- | :- | :- | :- | | getAndroidView() | View | null | Android 4.31 | 返回 Android 平台页面根 view | | getAndroidActivity() | Activity | null | Android 4.61 | 返回 Android 平台加载页面内容的 Activity | | getIOSView() | UIView | null | iOS(VDOM) UTS 插件 4.33 | 返回 iOS 平台页面根 view | | getHTMLElement() | UniElement | null | Web 4.31 | 返回页面 HTML Element 对象 |

这些方法主要用于 uts 插件场景下与原生层交互,例如在 Android 端拿到页面根 view 或 Activity 后注入原生能力。

DOM 查询:getElementById / querySelector / querySelectorAll

| 方法 | 返回类型 | 兼容性 | 描述 | | :- | :- | :- | :- | | getElementById(id: string.IDString | string) | UniElement | null | Web/Android/iOS 4.31,HarmonyOS 4.61 | 返回匹配特定 ID 的元素,不存在返回 null;ID 区分大小写且应唯一 | | querySelector(selector: string.cssSelectorString) | UniElement | null | Web/Android/iOS/HarmonyOS 5.0 | 返回页面中与选择器匹配的第一个元素,找不到返回 null | | querySelectorAll(selector: string.cssSelectorString) | UniElement[] | Android/iOS/HarmonyOS 5.0,iOS(VDOM) UTS 插件 5.21 | 返回页面中与选择器匹配的元素列表 |

getElementById如果需要获取指定的节点类型,需要使用as进行类型转换。这一组方法让页面级 DOM 查询成为可能,与全局的uni.getElementById(仅获取栈顶元素)相比,它们可以在指定页面的UniPage对象上操作,因而也适用于 dialogPage 内部元素。

截图与全屏:takeSnapshot / exitFullscreen

takeSnapshot(options: TakeSnapshotOptions): void对当前页面内容进行截图(5.02 起支持 Android/iOS/HarmonyOS)。注意:只针对页面内容截图,不包含状态栏、软键盘等系统 UI 元素,也不包含 pages.json 中定义的导航栏与 tabBar。截图行为随页面内容大小、根节点类型与平台不同而有所差异:

| 页面内容 | 根节点类型 | 截图高度 | | :- | :- | :- | | 超过一屏 | scroll-view 滚动容器 | 长图(完整内容) | | 超过一屏 | 非 scroll-view 容器 | 长图(完整内容),iOS 例外为屏幕高度 | | 不超过一屏 | scroll-view 滚动容器 | 内容高度(内容多高截图就多高) | | 不超过一屏 | 非 scroll-view 容器 | 屏幕高度(固定一屏高) |

options 参数:type(默认"file",目前仅支持保存到临时文件目录)、format(默认"png")、success(返回tempFilePath临时文件路径)、failcomplete回调。

exitFullscreen(options: ExitFullscreenOptions): void(Android/iOS/HarmonyOS 4.61)用于逆转此前 UniElement.requestFullscreen 的全屏效果,其fail回调中的errCode取值包括:106600(当前页面已有 element 处于全屏状态)、106601(当前 element 不支持全屏)、106602(当前页面没有 element 处于全屏状态)、106603(页面已销毁或尚未就绪)、106604(组件未就绪)。

监听类方法(HarmonyOS Vapor 5.0+)

UniPage 还提供一组以on/off配对的事件监听方法,返回 number 类型的监听 id,可用于取消监听:

  • onLayoutChange/offLayoutChange:监听/取消页面布局变化,回调参数UniPagePerformanceTimingduration,单位 ms);
  • onRenderChange/offRenderChange:监听/取消页面渲染变化,回调参数UniPagePerformanceRenderTimingupdateDurationduration,单位 ms);
  • onTouchStart/offTouchStartonTouchEnd/offTouchEnd:监听/取消页面触摸开始、结束事件,回调参数为 UniTouchEvent。

此外还有createElement(tagName: string): UniElement(HarmonyOS(VDOM) 4.63,创建组件),它们共同构成页面的低层能力集合。

仓库示例与自动化测试验证

getCurrentPages的完整可运行示例位于 src/pages/API/get-current-pages/get-current-pages.uvue,该页面在 pages.json 中注册,并通过group: "1,0,1"携带测试参数;set-page-style-disable-pull-down-refresh演示页则在 pages.json 中注册,enablePullDownRefresh默认配置为false

示例页的核心逻辑(节选):

const _getCurrentPages = () => { data.pages.length = 0 const pages = getCurrentPages() data.pages.push(pages[0].route) // 首页 route for (let i = 1; i < pages.length; i++) { data.pages.push(pages[i].route) // 逐层输出页面栈 } }

自动化测试 get-current-pages.test.js 以 jest + 自动化驱动的方式,在 Android / iOS / HarmonyOS / Web / 小程序多端对本文介绍的能力逐项断言,可作为「哪些能力真实可用」的直接证据:

  • getCurrentPages:跳转到pages/API/get-current-pages/get-current-pages?test=123后调用_getCurrentPages,断言首页 route 命中 tabBar 首页,验证页面栈顺序;
  • $page:通过page.callMethod('check$page')断言$page === getCurrentPages()栈顶,并验证组件内$page同样等价;
  • page-style:调用setPageStyle({ enablePullDownRefresh: false })getPageStyle()断言生效值翻转,并配合startPullDownRefresh截图比对;随后验证 Android 三键导航(androidThreeButtonNavigationBackgroundColor/androidThreeButtonNavigationStyle/androidThreeButtonNavigationTranslucent)与hideStatusBarhideBottomNavigationIndicator的动态设置;
  • getParentPage/getDialogPages:在主页面栈场景断言getParentPage()为 null、getDialogPages()为空数组(弹窗场景下的取值见 dialog-page 文档);
  • getElementById/querySelector/querySelectorAll:断言#check-get-element-by-id-btn可查、#does-not-exist不可查,querySelectorAll('.uni-common-mt')数量大于 1 且不存在的类返回空列表;
  • getAndroidView:仅 Android 端返回非空;getHTMLElement:仅 Web 端返回非空;getAndroidActivity:仅 Android 端断言成功;
  • takeSnapshot:App 端调用后断言 success/complete 回调计数,验证截图链路。

这套测试同时印证了各方法的平台适用性边界:例如getAndroidView仅在 Android 断言通过,getIOSView在非 iOS(VDOM) UTS 插件环境断言为 false,getHTMLElement仅在 Web 为 true——与上文的兼容性表格完全对应。

实战要点与最佳实践

  1. 取当前页面:组合式 API 优先使用getCurrentInstance()?.proxy?.$page,选项式使用this.$page;若在页面脚本中需要遍历整条链路,再使用getCurrentPages()并从末尾取当前页。
  2. 读取路由参数UniPage.options(UTSJSONObject)携带页面路由参数,例如get-current-pages.test.js中通过?test=123传入的参数可在page.options['test']读取。
  3. 动态样式setPageStyle只对表格中列出的属性生效,且各平台版本门槛不同;设置前可先getPageStyle()读取当前最终生效值再按需合并修改,避免覆盖其他属性。
  4. dialogPage 场景getCurrentPages()拿不到 dialogPage,必须先从主页面UniPagegetDialogPages()获取;在 dialogPage 内部取自身页面实例,应使用this.$page/$page
  5. 原生能力:uts 插件开发中,通过getAndroidView()/getAndroidActivity()/getIOSView()获取原生根视图与容器,是连接 uni-app x 页面与原生 SDK 的常用入口;注意getIOSView仅限 iOS(VDOM) UTS 插件环境。
  6. Web 摇树提醒:在 web 端使用setPageStyle({ enablePullDownRefresh: true })前,需确保项目某处真正使用过下拉刷新能力,否则相关代码会被摇树优化移除,导致动态开启无效。

参见

  • UniPage 完整属性与方法文档
  • dialogPage 概述与 openDialogPage / closeDialogPage
  • UTSJSONObject 内置对象文档
  • UniElement DOM 元素文档
  • 示例页源码
  • 自动化测试用例

【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询