uni-app 宽屏适配完全指南:leftWindow/rightWindow/topWindow 窗体 API 与分栏布局实战
uni-app 宽屏适配完全指南leftWindow/rightWindow/topWindow 窗体 API 与分栏布局实战【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-appuni-app 以移动端为先但从 2.9 版本起便内置了完整的 PC 宽屏适配方案其中页面窗体级适配leftWindow、rightWindow、topWindow是分栏式宽屏布局的核心骨架。本文以 wide-screen-adaptation.md 的窗体 API 文档为主线系统讲解三个窗体的配置方式、显示/隐藏/样式控制的完整 API 用法、窗体间通信机制并结合仓库中的真实配置src/pages.json、src/windows/与组件级、rpx 级适配方案给出从手机窄屏快速升级为 PC 宽屏应用的完整实战路径。一、宽屏适配的整体架构uni-app 宽屏适配由三部分组成页面窗体级适配leftWindow/rightWindow/topWindow、组件级适配match-media / 分栏与内容缩放拉伸处理rpx 基准控制。本文聚焦于页面窗体级方案即leftWindow、rightWindow、topWindow三个可扩展窗体。核心设计思想以手机屏幕对应的页面为主窗体mainWindow在主窗体的左侧、右侧、上方扩展出独立的辅助窗体区域。这些区域独立运行各窗体拥有独立的页面文件切换页面时可在各自的 window 内单独刷新而不是整屏刷新可自动显隐通过matchMedia规则设定生效的屏幕宽度范围宽屏出现、窄屏自动隐藏可交互通信窗体之间通过uni.$emit/uni.$on事件机制传递数据与状态。兼容性限制leftWindow、rightWindow、topWindow 以及本文所述的全部窗体 API 仅支持Web 端H5uni-app 4.0微信小程序、Android、iOS、HarmonyOS 均不支持详见下方各 API 兼容性表格。适用场景需要固定布局的复杂应用后台管理系统、文档系统多区域协同工作的场景新闻资讯、电商等列表 详情分栏式应用。仓库中的 uni-app 官方示例工程src/ 与 examples/hello-uvue正是以leftWindow topWindow构成上、左、右三栏布局的典型实现详见 src/pages.json 中的实际配置。二、窗体级适配 API 全解2.1 API 总览与兼容性| API | 功能 | 兼容性 | | :- | :- | :- | | uni.showLeftWindow(options) | 显示 leftWindow 窗体 | Web 4.0 | | uni.showRightWindow(options) | 显示 rightWindow 窗体 | Web 4.0 | | uni.showTopWindow(options) | 显示 topWindow 窗体 | Web 4.0 | | uni.hideLeftWindow(options) | 隐藏 leftWindow 窗体 | Web 4.0 | | uni.hideRightWindow(options) | 隐藏 rightWindow 窗体 | Web 4.0 | | uni.hideTopWindow(options) | 隐藏 topWindow 窗体 | Web 4.0 | | uni.getTopWindowStyle() | 获取 topWindow 窗体样式 | Web 4.0 | | uni.getLeftWindowStyle() | 获取 leftWindow 窗体样式 | Web 4.0 | | uni.getRightWindowStyle() | 获取 rightWindow 窗体样式 | Web 4.0 | | uni.setTopWindowStyle(options) | 设置 topWindow 窗体样式 | Web 4.0 | | uni.setLeftWindowStyle(options) | 设置 leftWindow 窗体样式 | Web 4.0 | | uni.setRightWindowStyle(options) | 设置 rightWindow 窗体样式 | Web 4.0 |六个 show/hide 系列 API 与六个 get/set 系列 API 的兼容性完全一致仅 Web 4.0 支持微信小程序 / Android / iOS / HarmonyOS 均为 x不支持。所有带 options 参数的接口其 options 类型均为 UniNamespace.CommonOptions带样式操作的接口set 系列的 options 类型为string合法值为PartialCSSStyleDeclaration或string.CSSURIString。2.2 show / hide 系列窗体的显示与隐藏2.2.1uni.showLeftWindow(options)showleftwindow显示 leftWindow 窗体。兼容性| Web | 微信小程序 | Android | iOS | HarmonyOS | | :- | :- | :- | :- | :- | | 4.0 | x | x | x | x |参数| 名称 | 类型 | 必填 | 兼容性 | | :- | :- | :- | :-: | | options | UniNamespace.CommonOptions | 是 | 微信小程序: x; Android: x; iOS: x; HarmonyOS: x |options 属性描述| 名称 | 类型 | 必备 | 兼容性 | 描述 | | :- | :- | :- | :-: | :- | | success | (result: any) void | 否 | 微信小程序: x; Android: x; iOS: x; HarmonyOS: x | 接口调用成功的回调函数 | | fail | (result: any) void | 否 | 微信小程序: x; Android: x; iOS: x; HarmonyOS: x | 接口调用失败的回调函数 | | complete | (result: any) void | 否 | 微信小程序: x; Android: x; iOS: x; HarmonyOS: x | 接口调用结束的回调函数调用成功、失败都会执行 |2.2.2uni.showRightWindow(options)showrightwindow显示 rightWindow 窗体。参数结构与兼容性同showLeftWindowoptions 为UniNamespace.CommonOptions回调success/fail/complete均为可选。2.2.3uni.showTopWindow(options)showtopwindow显示 topWindow 窗体。参数结构与兼容性同前两者。2.2.4uni.hideLeftWindow(options)hideleftwindow隐藏 leftWindow 窗体。options 为UniNamespace.CommonOptions必填回调可选。2.2.5uni.hideRightWindow(options)hiderightwindow隐藏 rightWindow 窗体。参数结构同hideLeftWindow。2.2.6uni.hideTopWindow(options)hidetopwindow隐藏 topWindow 窗体。参数结构同hideLeftWindow。2.2.7 实战示例根据屏幕宽度动态显示 / 隐藏窗体// 显示右侧窗体并在成功/失败时输出结果 uni.showRightWindow({ success: (result) { console.log(rightWindow 显示成功, result) }, fail: (result) { console.error(rightWindow 显示失败, result) }, complete: () { console.log(showRightWindow 调用结束) } }) // 隐藏左侧窗体 uni.hideLeftWindow({ success: (result) { console.log(leftWindow 已隐藏, result) } })2.3 get 系列获取窗体样式三个 get 接口均无参数、返回类型为any用于读取当前窗体运行时样式通常为 CSSStyleDeclaration 形式的样式对象。2.3.1uni.getTopWindowStyle()gettopwindowstyle获取 topWindow 窗体样式。| 类型 | | :- | | any |2.3.2uni.getLeftWindowStyle()getleftwindowstyle获取 leftWindow 窗体样式。| 类型 | | :- | | any |2.3.3uni.getRightWindowStyle()getrightwindowstyle获取 rightWindow 窗体样式。| 类型 | | :- | | any |实战示例const style uni.getLeftWindowStyle() console.log(当前 leftWindow 样式, style) // 可在拿到样式对象后继续读取/判断 width、height、backgroundColor 等属性2.4 set 系列动态设置窗体样式set 系列接口的 options 类型为string合法值有两种| 合法值 | 兼容性 | | :- | :-: | | PartialCSSStyleDeclaration | 微信小程序: x; Android: x; iOS: x; HarmonyOS: x | | string.CSSURIString | 微信小程序: x; Android: x; iOS: x; HarmonyOS: x |即支持传入一个 CSS 样式声明对象部分属性也支持传入 CSS URI 字符串如url(...)背景资源。2.4.1uni.setTopWindowStyle(options)settopwindowstyle设置 topWindow 窗体样式。options 类型为string必填。2.4.2uni.setLeftWindowStyle(options)setleftwindowstyle设置 leftWindow 窗体样式。options 类型为string必填。2.4.3uni.setRightWindowStyle(options)setrightwindowstyle设置 rightWindow 窗体样式。options 类型为string必填。实战示例// 方式一以样式对象设置 leftWindow 宽度与背景 uni.setLeftWindowStyle({ width: 320px, backgroundColor: #f8f8f8 }) // 方式二以 CSS URI 字符串设置背景图 uni.setTopWindowStyle(url(/static/banner.png)) // 读取设置后的结果 const style uni.getRightWindowStyle()三、通用类型说明GeneralCallbackResult generalcallbackresult-values所有 show/hide 接口的 success / fail 回调均可能返回该通用结果对象| 名称 | 类型 | 必备 | 描述 | | :- | :- | :- | :- | | errMsg | string | 是 | 错误信息 |errMsg为接口调用结果描述成功时为xxx:ok形式失败时为对应的错误信息可在fail回调中读取用于排查问题。四、pages.json 窗体配置详解窗体级适配的声明配置在pages.json的顶层进行与globalStyle、pages平级仓库官方示例 src/pages.json 的真实配置如下{ leftWindow: { path: windows/left-window.uvue, style: { width: 350px } }, topWindow: { path: windows/top-window.uvue, style: { height: 60px } }, pages: [] }4.1 各窗体的配置项列表三个窗体topWindow / leftWindow / rightWindow的配置项结构完全一致详见 pagesjson.md| 属性 | 类型 | 必填 | 兼容性 | 描述 | | :- | :- | :- | :- | :- | | path | string | 否 | Web: 4.0; 微信小程序: x; Android: x; iOS: x; HarmonyOS: x | 配置页面路径 | | style | object | 否 | Web: 4.0; 微信小程序: x; Android: x; iOS: x; HarmonyOS: x | 配置页面窗口表现 | | matchMedia | matchMedia 配置项列表 | 否 | Web: 4.0; 微信小程序: x; Android: x; iOS: x; HarmonyOS: x | 配置显示该窗口的规则 |matchMedia 配置项列表三个窗体相同| 属性 | 类型 | 默认值 | 必填 | 兼容性 | 描述 | | :- | :- | :- | :- | :- | :- | | minWidth | number | 768 | 否 | Web: 4.0; 微信小程序: x; Android: x; iOS: x; HarmonyOS: x | 当设备可见区域宽度 ≥ minWidth 时显示该 window |4.2 页面级显隐控制与 maxWidth除窗体自身的matchMedia外pages.json 还支持在页面pages数组项与全局globalStyle维度控制窗体的显示| 属性 | 类型 | 默认值 | 描述 | | :- | :- | :- | :- | | leftWindow | boolean | true | 当存在 leftWindow 时当前页面/全局是否显示 leftWindow | | topWindow | boolean | true | 当存在 topWindow 时当前页面/全局是否显示 topWindow | | rightWindow | boolean | true | 当存在 rightWindow 时当前页面/全局是否显示 rightWindow | | maxWidth | number | - | 单位 px当浏览器可见区域宽度大于 maxWidth 时两侧留白小于等于 maxWidth 时页面铺满不同页面支持配置不同 maxWidthmaxWidth leftWindow(可选) page(页面主体) rightWindow(可选) |其中maxWidth用于限定内容区的最大宽度超过该宽度后浏览器两侧留白避免超宽屏下内容过度拉伸非常适合内容型站点。4.3 完整配置示例{ globalStyle: { maxWidth: 1200 }, topWindow: { path: responsive/top-window.vue, style: { height: 44px } }, leftWindow: { path: responsive/left-window.vue, style: { width: 300 } }, rightWindow: { path: responsive/right-window.vue, style: { width: calc(100vw - 400px) }, matchMedia: { minWidth: 768 } } }要点说明topWindow.style.height顶部窗体高度支持44px等固定值与百分比leftWindow.style.width左侧窗体宽度支持数字px或300px字符串rightWindow.style.width右侧窗体宽度可用calc()动态计算如calc(100vw - 400px)表示占满视口减去左栏与主栏matchMedia.minWidth默认值为 768即默认在 768px 以上才显示该窗体。五、窗体页面实现与通信实战5.1 窗体页面文件以仓库官方实现为例仓库官方示例中leftWindow 与 topWindow 的页面文件位于 src/windows/left-window.uvue左侧导航窗体宽度 350px内部通过component :isactive动态挂载 tab 页作为二级导航top-window.uvue顶部窗体高度 60px。从 left-window.uvue 可以看到官方在窗体内部同样使用uni.createMediaQueryObserver(this).observe({ minWidth: 768 }, matched ...)来感知宽屏状态这说明窗体 API 与matchMedia媒体查询机制在宽屏适配中协同工作窗体页面是独立运行的 Vue/uvue 组件实例可持有自己的 data、computed、watch 与生命周期。5.2 窗体间通信事件总线窗体与主页面之间通过uni.$emit/uni.$on事件总线通信。经典列表 详情分栏场景!-- responsive/right-window.vue右侧详情窗体 -- template view !-- 将原详情页面 /pages/detail/detail 作为组件复用 -- pages-detail-detail refdetailPage/pages-detail-detail /view /template script setup import { onUnmounted, ref } from vue const detailPage ref(null) // 监听列表页点击触发的自定义事件刷新详情 const updateDetail (e) { detailPage.value?.load(e.detail) } uni.$on(updateDetail, updateDetail) onUnmounted(() { uni.$off(updateDetail, updateDetail) }) /script// 主窗体列表页宽屏时通知右侧窗体刷新窄屏时跳转新页面 const goDetail (detail) { if (instance?.proxy?._isWidescreen) { // 宽屏触发右侧窗体事件 uni.$emit(updateDetail, { detail: encodeURIComponent(JSON.stringify(detail)) }) } else { // 窄屏navigateTo 打开详情页 uni.navigateTo({ url: /pages/detail/detail?query encodeURIComponent(JSON.stringify(detail)) }) } }关键点页面复用/pages/detail/detail页面可自动转化为pages-detail-detail组件在窗体中直接引用无需重写详情逻辑同一套代码维护宽屏分栏、窄屏跳转共用一套业务代码迭代时无需多处升级事件配对务必在onUnmounted中uni.$off注销监听避免窗体销毁后事件泄漏。5.3 leftWindow 适合做什么导航重组把手机竖屏上依赖的多级 tab、宫格导航重组为 leftWindow 中的 tree / 折叠面板导航PC Admin 管理控制台leftWindow 天然适合左侧菜单栏 右侧内容区的后台布局官方基于 uni-app PC 版还推出了 unicloud Admin 供参考。六、向宽屏升级的实战路径6.1 思路现有小屏内容放哪个 window已有为小屏设计的 uni-app 应用适配大屏时先理清现有小屏内容放在哪个 window 里首页是列表、二级页是详情 → 把列表作为主 window右侧扩展rightWindow放详情新闻资讯类模板的经典做法首页有很多 tab / 宫格 → 重组进leftWindow作为导航需要在所有页面上方展示全局信息条 / 工具条 → 使用topWindow。6.2 第一步声明窗体按 第四节 在 pages.json 中配置窗体路径、样式与 matchMedia。6.3 第二步复用详情页面为窗体组件窗体页面不需要重写详情逻辑直接把原详情页当组件引入路径/pages/detail/detail转为组件名pages-detail-detail。6.4 第三步主窗体按宽窄屏分流交互在主窗体列表页通过uni.getWindowInfo().windowWidth 768或uni.getDeviceInfo().deviceTypepad || pc判断宽屏宽屏uni.$emit通知窗体窄屏uni.navigateTo跳转见 5.2 示例。七、组件级适配与 rpx 补充方案当需要跨端pad、折叠屏分栏、或在单页面内做响应式布局时窗体级方案仅 Web不再适用可改用以下方案7.1 组件级适配分栏与 match-media利用vue 文件既可作页面又可作组件的特性在列表页中并排放置 list 组件与 detail 组件template view styledisplay: flex;flex-direction: row; view :classisWide ? list-narrow : list-wide view v-for(item, index) in listData :keyindex text clickshowDetail(item.id){{ item.title }}/text /view /view detail v-ifisWide stylewidth: 50%;/detail /view /template script setup import { ref } from vue import { onLoad } from dcloudio/uni-app import detail from ./detail const isWide ref(false) onLoad(() { const deviceType uni.getDeviceInfo().deviceType isWide.value deviceType pad || deviceType pc }) const showDetail (id) { if (isWide.value) { uni.$emit(detailId, id) // 宽屏事件通知右侧组件 } else { uni.navigateTo({ url: /pages/detail?id id }) // 窄屏跳转 } } /script style .list-wide { width: 100%; } .list-narrow { width: 50%; border-right: 1px solid #000; } /style配套的组件级媒体查询方案还有match-media组件在组件内放置内容并指定 media query条件满足时展示与uni.createMediaQueryObserver方法仓库官方 leftWindow 页面即使用该方法监听minWidth: 768。组件级方案的优势是显式、可数据绑定、可嵌套、封装性强。7.2 rpx 宽屏基准控制uni-app 2.9 将 rpx 默认最大适配宽度设为 960px防止宽屏下界面被等比放大到惨不忍睹。可在 pages.json 的 globalStyle 中自定义{ globalStyle: { rpxCalcMaxDeviceWidth: 960, rpxCalcBaseDeviceWidth: 375, rpxCalcIncludeWidth: 750 } }| 参数 | 默认值 | 说明 | | :- | :- | :- | | rpxCalcMaxDeviceWidth | 960 | rpx 计算支持的最大设备宽度px超过后不再按屏宽缩放 | | rpxCalcBaseDeviceWidth | 375 | 超出最大宽度后采用的基准设备宽度px | | rpxCalcIncludeWidth | 750 | 特殊处理值rpx始终按实际设备宽度计算如配置 750rpx 始终按 100% 屏宽计算 |注意以 750rpx 当 100% 使用是不推荐的写法即使 nvue 不支持百分比也应使用 flex 撑满。若代码中确有此类写法可配置rpxCalcIncludeWidth兜底或改用postcss-px-to-viewport等工具将 rpx 转为 px 后采用局部拉伸 flex 自适应策略。八、小结uni-app 的宽屏适配以leftWindow / rightWindow / topWindow 页面窗体级方案为核心通过 pages.json 顶层配置声明窗体与生效宽度通过 wide-screen-adaptation.md 中的 12 个窗体 API 在运行时控制窗体的显示、隐藏与样式配合uni.$emit/uni.$on事件总线实现窗体间通信即可把一套手机窄屏应用快速升级为 PC 宽屏分栏应用且业务代码单一维护。跨端分栏需求则改用组件级方案页面即组件 match-media / createMediaQueryObserver并善用 rpx 基准配置控制内容缩放。仓库官方示例配置位于 src/pages.json 与 src/windows/可作为上手参考。【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考