页面
页面简介
在uni-app项目中,一个页面就是一个符合Vue单文件组件(SFC)规范的.vue文件。具体的文件类型根据版本有所不同:
- 在uni-app js引擎版中,页面可以是
.vue文件或.nvue文件。这两者均全平台支持,主要差异在于App平台:.vue文件使用Webview渲染,而.nvue文件使用原生渲染。同一个页面可以同时存在.vue和.nvue两个版本,在pages.json中注册路由时无需包含文件后缀。当两者重名时,优先级规则为:在非App平台,优先使用.vue文件;在App平台,则优先使用.nvue文件。 - 在uni-app x中,页面是
.uvue文件。uni-app x没有js引擎和Webview,因此不支持与Vue页面并存。需要注意的是,在Android平台的uni-app x上,每个页面都是一个全屏的activity,不支持透明效果。
页面管理
新建与删除页面
uni-app的页面默认保存在项目根目录的pages目录下。每次新建页面后,都必须在pages.json配置文件的pages列表中进行注册,否则该页面在编译时将被忽略。通过HBuilderX开发时,在项目上右键选择“新建页面”,可以自动完成页面注册,并且HBuilderX还提供了多种常用的页面模板以提升开发效率。
新建页面时可以选择是否创建同名目录。如果页面结构复杂,需要拆分为多个附属的JS、CSS或组件文件,使用目录进行归纳比较合适;如果只有一个单独的页面文件,则无需创建额外目录。
删除页面需要完成两项操作:一是删除对应的.vue、.nvue或.uvue文件;二是删除pages.json中pages列表里对应的配置项。页面改名操作同理,需要依次修改文件名和pages.json中的配置。
pages.json与首页设置
pages.json是项目的核心页面管理配置文件,负责页面路由注册、页面参数配置(如原生标题栏、下拉刷新等)以及首页tabbar等众多功能。在该文件pages配置项中列出的第一个页面,将被设置为整个应用的首页(启动页)。
页面内容构成
uni-app页面基于Vue规范,每个页面文件包含三个根节点标签:
<template>模板区:用于编写页面结构,其中书写的是Vue组件,而非普通的HTML标签。在Vue2中,<template>下只能有一个根节点;而在Vue3中,则允许多个根节点,可以减少一层嵌套。uni-app x仅支持Vue3。<script>脚本区:用于编写页面逻辑。可以通过lang属性指定脚本语言(如在Vue/nvue中可指定TypeScript,在uvue中则固定为UTS)。页面级代码主要写在export default {}内部。写在export default {}外部的代码(如模块引入、类型定义等)会在应用启动时执行,需谨慎编写,以避免影响启动性能和内存管理。<style>样式区:用于编写页面样式,其语法与Web的CSS基本相同。需要注意的是,nvue或uvue页面使用原生渲染,所支持的CSS特性是受限的。
页面生命周期
uni-app页面除了支持Vue组件生命周期外,还支持一系列特有的页面生命周期函数,这些函数在组合式API中的用法在Vue2和Vue3中存在区别。
核心生命周期函数
- onLoad: 监听页面加载。此时响应式数据、计算属性、方法等均已设置完成,参数为上一个页面传递过来的数据。
- onShow: 监听页面显示。每次页面出现在屏幕上时都会触发,包括从下级页面返回后重新显示当前页面。
- onReady: 监听页面初次渲染完成。此时组件已挂载完成,DOM可用。
- onHide: 监听页面隐藏。
- onUnload: 监听页面卸载。
其他常用生命周期
- onPullDownRefresh: 监听用户下拉动作,用于实现下拉刷新。
- onReachBottom: 监听页面滚动到底部的事件,常用于加载下一页数据。可在
pages.json中通过onReachBottomDistance配置触发距离。 - onPageScroll: 监听页面滚动,参数包含滚动距离。注意在此函数中应避免编写复杂的交互逻辑,以防造成通信层卡顿。
- onBackPress: 监听页面返回,可区分返回来源(如返回键或
uni.navigateBack方法),并有机会阻止默认返回行为。 - onTabItemTap: 点击底部tab时触发。
页面加载时序与优化
页面加载遵循一个特定的时序:框架首先根据pages.json创建页面(此时原生导航栏最快显示),然后创建初始静态DOM,接着触发onLoad。在onLoad中适合进行接受参数、联网请求数据等操作。之后页面转场动画开始,当UI层完成真实元素创建后触发onReady,此时方可自由操作DOM元素。最后转场动画结束。
了解此时序有助于解决常见问题:
- 优化白屏:减少首屏DOM数量;在
onLoad而非onReady中提前发起网络请求;在pages.json中配置原生导航栏和背景色;对于内容较少的页面,使用加载组件或骨架屏进行占位。 - 避免卡住动画:减少页面DOM复杂度;避免在
onLoad中执行大量同步耗时运算(在uni-app x Android上尤其要注意,默认在UI线程运行)。
onShow和onHide会重复触发,例如从页面A跳转到页面B,A触发onHide,B触发onShow;当B关闭返回A时,A会再次触发onShow。
页面调用接口与通讯
获取应用与页面实例
getApp(): 用于获取当前应用实例,通常用于访问全局数据globalData或调用App.vue中定义的方法。getCurrentPages(): 用于获取当前页面栈的实例数组,第一个元素为首页,最后一个元素为当前页面。每个页面实例包含路由等信息,此函数仅用于获取状态,请勿修改页面栈。
页面通讯
uni-app提供了全局的事件订阅与发布机制,可用于跨页面、跨组件通讯:
uni.$emit(eventName, OBJECT): 触发全局自定义事件。uni.$on(eventName, callback): 监听全局自定义事件。uni.$once(eventName, callback): 监听全局自定义事件,但仅触发一次。uni.$off(eventName, callback): 移除事件监听器。
使用时需注意及时清理监听,例如在页面onLoad中监听的事件,应在onUnload中移除。
路由
uni-app页面路由由框架统一管理,开发者需在pages.json中配置路由。路由跳转可通过<navigator>组件或调用uni.navigateTo等API实现。框架以栈的形式管理页面,不同的跳转方式(如navigateTo、redirectTo、navigateBack、switchTab、reLaunch)对应页面栈的不同变化。
nvue开发与vue开发的常见区别
基于原生引擎渲染的nvue页面,在开发上与Web渲染的vue页面存在一些重要区别:
- 布局:nvue页面仅支持Flex布局,不支持其他布局方式(如浮动、百分比)。布局排列方向默认为竖向(
column)。 - 样式与组件:
- 文字内容必须放在
<text>组件内,不能直接在<view>等组件中书写。 - 只有
<text>组件可以设置字体大小和颜色。 - 不支持背景图片,但可通过
<image>组件和层级模拟。 - CSS选择器支持较少,主要使用class选择器。
- 控制显隐推荐使用
v-if,而非v-show。
- 文字内容必须放在
- 页面行为:
- 页面内容过高时不会自动滚动,需要将内容置于可滚动组件(如
scroll-view、list)内。但nvue页面在编译为uni-app模式时,框架通常会自动在外层套一个scroller。 - 没有全局的
bounce回弹效果,仅部分列表组件自带。
- 页面内容过高时不会自动滚动,需要将内容置于可滚动组件(如
- 性能与注意事项:
- Android端nvue组件默认透明,建议设置
background-color以避免重影。 - 避免在Android端使用大量且样式不一的圆角边框,以免造成性能问题。
- 强烈建议在nvue页面使用原生导航栏,以获得最佳的启动和转场性能。
- 定义在
App.vue中的全局JS变量对nvue页面不生效,但globalData和Vuex生效。
- Android端nvue组件默认透明,建议设置