# 页面

# Page Introduction

uni-app项目中,一个页面就是一个符合Vue SFC规范的 vue 文件。

  • 在 uni-app js 引擎版中,后缀名是.vue文件或.nvue文件。 这些页面均全平台支持,差异在于当 uni-app 发行到App平台时,.vue文件会使用webview进行渲染,.nvue会使用原生进行渲染,详见:nvue原生渲染

    一个页面可以同时存在vue和nvue,在pages.json的路由注册中不包含页面文件名后缀,同一个页面可以对应2个文件名。重名时优先级如下:

    • 在非app平台,先使用vue,忽略nvue
    • 在app平台,使用nvue,忽略vue
  • 在 uni-app x 中,后缀名是.uvue文件

    uni-app x 中没有js引擎和webview,不支持和vue页面并存。

    uni-app x 在app-android上,每个页面都是一个全屏activity,不支持透明。

# 页面管理

# 新建页面

uni-app中的页面,默认保存在工程根目录下的pages目录下。

每次新建页面,均需在pages.json中配置pages列表;未在pages.json -> pages 中注册的页面,uni-app会在编译阶段进行忽略。pages.json的完整配置参考:页面配置

When developing a uni-app project through HBuilderX, right-click on the uni-app project and "New Page", HBuilderX will automatically complete the page registration in pages.json, making development more convenient.

At the same time, HBuilderX also has built-in common page templates (such as text lists, product lists, etc.). Choosing these templates can greatly improve your development efficiency.

新建页面时,可以选择是否创建同名目录。创建目录的意义在于:

  • 如果你的页面较复杂,需要拆分多个附属的js、css、组件等文件,则使用目录归纳比较合适。
  • 如果只有一个页面文件,大可不必多放一层目录。

# 删除页面

删除页面时,需做两件工作:

  • 删除.vue文件、.nvue.uvue文件
  • 删除pages.json -> pages列表项中的配置 (如使用HBuilderX删除页面,会在状态栏提醒删除pages.json对应内容,点击后会打开pages.json并定位到相关配置项)

# 页面改名

操作和删除页面同理,依次修改文件和 pages.json

# pages.json

pages.json是工程的页面管理配置文件,包括:页面路由注册、页面参数配置(原生标题栏、下拉刷新...)、首页tabbar等众多功能。

其篇幅较长,另见 pages.json

# 设置应用首页

pages.json -> pages配置项中的第一个页面,作为当前工程的首页(启动页)。

{
	"pages": [
		{
			"path": "pages/index/index", //名字叫不叫index无所谓,位置在第一个,就是首页
			"style": {
				"navigationBarTitleText": "首页" //页面标题
			}
		},
		{
			"path": "pages/my",
			"style": {
				"navigationBarTitleText": "我的"
			}
		},
	]
}

# 页面内容构成

uni-app 页面基于 vue 规范。一个页面内,有3个根节点标签:

  • 模板组件区 <template>
  • 脚本区 <script>
  • 样式区 <style>
<template>
	<view class="content">
		<button @click="buttonClick">{{title}}</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: "Hello world", // 定义绑定在页面上的data数据
			}
		},
		onLoad() {
			// 页面启动的生命周期,这里编写页面加载时的逻辑
		},
		methods: {
			buttonClick: function () {
				console.log("按钮被点了")
			},
		}
	}
</script>

<style>
	.content {
		width: 750rpx;
		background-color: white;
	}
</style>

# template模板区

template中文名为模板,它类似html的标签。但有2个区别:

  1. html中 scriptstyle 是 html 的二级节点。但在 vue 文件中,templatescriptstyle 这3个是平级关系。
  2. html 中写的是 web 标签,但 vue 的 template 中写的全都是 vue 组件,每个组件支持属性、事件、 vue 指令,还可以绑定 vue 的 data 数据。

在vue2中,template 的二级节点只能有一个节点,一般是在一个根 view 下继续写页面组件(如上示例代码)。

但在vue3中,template可以有多个二级节点,省去一个层级,如下:

<template>
	<view>
		<text>标题</text>
	</view>
	<scroll-view>

	</scroll-view>
</template>

可以在 manifest 中切换使用 Vue2 还是 Vue3。

注意:uni-app x 中只支持 Vue3。

# script 脚本区

script中编写脚本,可以通过lang属性指定脚本语言。

  • 在vue和nvue中,默认是js,可以指定ts。
  • 在uvue中,仅支持uts,不管script的lang属性写成什么,都按uts编译。
<script lang="ts">
</script>

在vue的选项式(option)规范中,script下包含 export default {}。除了选项式,还有 组合式 写法。

页面级的代码大多写在 export default {} 中。写在里面的代码,会随着页面关闭而关闭。

# export default 外的代码

写在 export default {} 外面的代码,一般有几种情况:

  1. 引入第三方 js/ts 模块
  2. 引入非 easycom 的组件(一般组件推荐使用easycom,无需导入注册)
  3. 在 ts/uts 中,对 data 进行类型定义
  4. 定义作用域更大的变量
<script lang="ts">
	const TAB_OFFSET = 1; // 外层静态变量不会跟随页面关闭而回收
	import charts from 'charts.ts'; // 导入外部js/ts模块
	import swiperPage from 'swiper-page.vue'; //导入非easycom的组件
	type GroupType = {
		id : number,
		title : string
	} // 在ts中,为下面data数据的 groupList 定义类型
	export default {
		components: {
		    swiperPage
		}, // 注册非easycom组件
		data() {
			return {
				groupList: [
					{ id: 1, title: "第一组" },
					{ id: 2, title: "第二组" },
				] as GroupType[], // 为数据groupList定义ts类型
			}
		},
		onLoad() {},
		methods: {}
	}
</script>

开发者应谨慎编写 export default {} 外面的代码,这里的代码有2个注意事项:

  1. 影响应用性能。这部分代码在应用启动时执行,而不是页面加载。如果这里的代码写的太复杂,会影响应用启动速度,占用更多内存。
  2. 不跟随组件、页面关闭而回收。在外层的静态变量不会跟随页面关闭而回收。如果必要你需要手动处理。比如 beforeDestroydestroyed 生命周期进行处理。

# export default 里的代码

export default {} 里的内容,是页面的主要逻辑代码。包括几部分:

  1. data:template模板中需要使用的数据。具体 另见
  2. 页面生命周期:如页面加载、隐藏、关闭,具体 见下
  3. methods方法,如按钮点击、屏幕滚动

如下页面代码的逻辑是:

  1. 在data中定义了title,初始值是"点我"
  2. 在页面中放置了一个button组件,按钮文字区使用{{}}模板写法,里面写title,把data里的title绑定到按钮的文字区,即按钮的初始文字是"点我"
  3. 按钮的点击事件@click,指向了methods里的一个方法buttonClick,点击按钮即触发这个方法的执行
  4. buttonClick方法里通过this.title的方式,访问data数据,并重新赋值为"被点了"。由于vue中data和界面是双向绑定,修改data中的title后,因为按钮文字绑定了title,会自动更新按钮的文字。

整体效果就是,刚开始按钮文字是"点我",点一下后按钮文字变成了"被点了"

<template>
	<view>
		<button @click="buttonClick">{{title}}</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: "点我", // 定义绑定在页面上的data数据
				// 多个data在这里继续定义。逗号分隔
			}
		},
		onLoad() {
			// 页面启动的生命周期,这里编写页面加载时的逻辑
		},
		// 多个页面生命周期监听,在这里继续写。逗号分隔
		methods: {
			buttonClick: function () {
				this.title = "被点了"
			},
			// 多个方法,在这里继续写。逗号分隔
		}
	}
</script>

本章节为页面代码介绍,并非vue教程,了解data数据需详见

# style样式区

style的写法与web的css基本相同。

如果页面是nvue或uvue,使用原生渲染而不是webview渲染,那么它们支持的css是有限的。

详见css文档

# 页面生命周期

uni-app 页面除支持 Vue 组件生命周期外还支持下方页面生命周期函数,当以组合式 API 使用时,在 Vue2 和 Vue3 中存在一定区别,请分别参考:Vue2 组合式 API 使用文档Vue3 组合式 API 使用文档

Function name Instruction Platform difference description Minimum version
onInit 监听页面初始化,其参数同 onLoad 参数,为上个页面传递的数据,参数类型为 Object(用于页面传参),触发时机早于 onLoad 百度小程序 3.1.0+
onLoad 监听页面加载,该钩子被调用时,响应式数据、计算属性、方法、侦听器、props、slots 已设置完成,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例
onShow 监听页面显示,页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
onReady 监听页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用,注意如果渲染速度快,会在页面进入动画完成前触发
onHide listen to page hiding
onUnload listen to page uninstall
onResize 监听窗口尺寸变化 App、微信小程序、快手小程序
onPullDownRefresh 监听用户下拉动作,一般用于下拉刷新,参考示例
onReachBottom The event that a page scrolls to the bottom (not scroll-view to the bottom) is often used to pull down the data on the next page. See the precautions below for details
onTabItemTap 点击 tab 时触发,参数为Object,具体见下方注意事项 微信小程序、QQ小程序、支付宝小程序、百度小程序、H5、App、快手小程序、京东小程序
onShareAppMessage 用户点击右上角分享 微信小程序、QQ小程序、支付宝小程序、抖音小程序、飞书小程序、快手小程序、京东小程序
onPageScroll 监听页面滚动,参数为Object nvue不支持
onNavigationBarButtonTap 监听原生标题栏按钮点击事件,参数为Object App、H5
onBackPress 监听页面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack;详见 app、H5、支付宝小程序
onNavigationBarSearchInputChanged Listen to the input content change event of search input box of the native title bar App, H5 1.6.0
onNavigationBarSearchInputConfirmed Listen to the search event of search input box of the native title bar, which is triggered when the user clicks the "Search" button on the soft keyboard. App, H5 1.6.0
onNavigationBarSearchInputClicked Listen to the click event of the native title bar search input box (only triggered when the searchInput configuration in pages.json is disabled to true) App, H5 1.6.0
onShareTimeline Monitor users click on the upper right corner to forward to Moments WeChat MiniApp 2.8.1+
onAddToFavorites Monitor users click on the upper right corner to save WeChat MiniApp, QQ MiniApp 2.8.1+

# 页面加载时序介绍

接下来我们介绍onLoad、onReady、onShow的先后关系,页面加载的详细流程。

  1. uni-app框架,首先根据pages.json的配置,创建页面

所以原生导航栏是最快显示的。页面背景色也应该在这里配置。

  1. 根据页面template里的组件,创建dom。

这里的dom创建仅包含第一批处理的静态dom。对于通过js/uts更新data然后通过v-for再创建的列表数据,不在第一批处理。

要注意一个页面静态dom元素过多,会影响页面加载速度。在uni-app x Android版本上,可能会阻碍页面进入的转场动画。 因为此时,页面转场动画还没有启动。

  1. 触发onLoad

此时页面还未显示,没有开始进入的转场动画,页面dom还不存在。

所以这里不能直接操作dom(可以修改data,因为vue框架会等待dom准备后再更新界面);在 app-uvue 中获取当前的activity拿到的是老页面的activity,只能通过页面栈获取activity。

onLoad比较适合的操作是:接受上页的参数,联网取数据,更新data。

手机都是多核的,uni.request或云开发联网,在子线程运行,不会干扰UI线程的入场动画,并行处理可以更快的拿到数据、渲染界面。

但onLoad里不适合进行大量同步耗时运算,因为此时转场动画还没开始。

尤其uni-app x 在 Android上,onLoad里的代码(除了联网和加载图片)默认是在UI线程运行的,大量同步耗时计算很容易卡住页面动画不启动。除非开发者显式指定在其他线程运行。

  1. 转场动画开始

新页面开始进入的转场动画,动画默认耗时300ms,可以在路由API中调节时长。

  1. 页面onReady

第2步创建dom是虚拟dom,dom创建后需要经历一段时间,UI层才能完成了页面上真实元素的创建,即触发了onReady。

onReady后,页面元素就可以自由操作了,比如ref获取节点。同时首批界面也渲染了。

注意:onReady和转场动画开始、结束之间,没有必然的先后顺序,完全取决于dom的数量和复杂度。

如果元素排版和渲染够快,转场动画刚开始就渲染好了;

大多情况下,转场动画走几格就看到了首批渲染内容;

如果元素排版和渲染过慢,转场动画结束都没有内容,就会造成白屏。

联网进程从onLoad起就在异步获取数据更新data,如果服务器速度够快,第二批数据也可能在转场动画结束前渲染。

  1. 转场动画结束

再次强调,5和6的先后顺序不一定,取决于首批dom渲染的速度。

# 页面加载常见问题

了解了页面加载时序原理,我们就知道如何避免页面加载常见的问题:

  • 优化白屏的方法:
  1. 页面dom太多,注意有的组件写的不好,会拖累整体页面。uni-app x 里减少dom数量的策略,详见
  2. 联网不要在onReady里,那样太慢了,在onLoad里早点联网
  3. 在pages.json里配置原生导航栏和背景色
  4. 有的页面template内容非常少,整页就是一个需要联网加载的列表,这会造成虽然首批dom飞快渲染了,但页面其实还是白的,联网后才能显示字和图。 此时需要在template里做一些简单占位组件,比如loading组件、骨架屏,让本地先显示一些内容。
  • 卡住动画不启动的原因:
  1. 页面dom太多,注意有的组件写的不好,会拖累整体页面。uni-app x 里减少dom数量的策略,详见
  2. onLoad里执行了耗时的同步计算

# onShow和onHide

注意页面显示,是一个会重复触发的事件。

a页面刚进入时,会触发a页面的onShow。

当a跳转到b页面时,a会触发onHide,而b会触发onShow。

但当b被关闭时,b会触发onUnload,此时a再次显示出现,会再次触发onShow。

在tabbar页面(指pages.json里配置的tabbar),不同tab页面互相切换时,会触发各自的onShow和onHide。

# onInit

注意

  • Only Baidu Mini Program base library 3.260 and above supports onInit life cycle
  • Other versions or platforms can use the onLoad life cycle for compatibility at the same time, be careful to avoid repeating the same logic
  • The logic that does not depend on page parameters can be replaced directly by the created life cycle

# onLoad

注意

  • uni-app x android 平台,如需获取 activity 实例,此时当前页面的 activity 实例并未创建完成,会获取到上一个页面的 activity 实例(首页会获取应用默认的 activity 实例)。如需获取当前页面的 activity 实例,应在 onShowonReady 生命周期中获取。

# onReachBottom

可在pages.json里定义具体页面底部的触发距离onReachBottomDistance

比如设为50,那么滚动页面到距离底部50px时,就会触发onReachBottom事件。

如使用scroll-view导致页面没有滚动,则触底事件不会被触发。scroll-view滚动到底部的事件请参考scroll-view的文档。

# onPageScroll

参数说明

Attribute Type Instruction
scrollTop Number 页面在垂直方向已滚动的距离(单位px)
onPageScroll : function(e) { //nvue暂不支持滚动监听,可用bindingx代替
	console.log("滚动距离为:" + e.scrollTop);
},

注意

  • onPageScroll里不要写交互复杂的js,比如频繁修改页面。因为这个生命周期是在渲染层触发的,在非h5端,js是在逻辑层执行的,两层之间通信是有损耗的。如果在滚动过程中,频发触发两层之间的数据交换,可能会造成卡顿。(uvue在app端无此限制)
  • 在webview渲染时,比如app-vue、微信小程序、H5中,也可以使用wxs监听滚动,参考;在app-nvue中,可以使用bindingx监听滚动,参考
  • 如果想实现滚动时标题栏透明渐变,在App和H5下,可在pages.json中配置titleNView下的type为transparent,参考。(uni-app x不支持)
  • 如果需要滚动吸顶固定某些元素,推荐使用css的粘性布局,参考插件市场。插件市场也有其他js实现的吸顶插件,但性能不佳,需要时可自行搜索。(uni-app x可自由在uts中设置固定位置)

# onBackPress

参数说明

属性 类型 说明
from String 触发返回行为的来源:'backbutton'——左上角导航栏按钮及安卓返回键;'navigateBack'——uni.navigateBack() 方法。支付宝小程序端不支持返回此字段
export default {
	onBackPress(options) {
		console.log('from:' + options.from)
	}
}

注意

  • onBackPress上不可使用async,会导致无法阻止默认返回
  • 支付宝小程序只有真机可以监听到非navigateBack引发的返回事件(使用小程序开发工具时不会触发onBackPress),不可以阻止默认返回行为

详细说明及使用:onBackPress 详解

# onTabItemTap

参数说明

Attribute Type Instruction
index Number The serial number of the clicked tabItem, starting from 0
pagePath String The page path of the clicked tabItem
text String The buttom text of the clicked tabItem
onTabItemTap : function(e) {
	console.log(e);
	// Return format of e is json object: {"index":0,"text":"Home page","pagePath":"pages/index/index"}
},

注意

  • onTabItemTap常用于点击当前tabitem,滚动或刷新当前页面。如果是点击不同的tabitem,一定会触发页面切换。
  • 如果想在App端实现点击某个tabitem不跳转页面,不能使用onTabItemTap,可以使用plus.nativeObj.view放一个区块盖住原先的tabitem,并拦截点击事件。
  • 支付宝小程序平台onTabItemTap表现为点击非当前tabitem后触发,因此不能用于实现点击返回顶部这种操作

# onNavigationBarButtonTap

参数说明

Attribute Type Instruction
index Number Subscript of native title bar button array
onNavigationBarButtonTap : function (e) {
	console.log(e);
	// The return format of e is a json object: {"text":"test","index":0}
}

Notice

# Component life cycle

The uni-app component supports the same lifecycle as the vue standard components. There is no page-level onLoad and other life cycles here:

Function name Instruction Platform difference description Minimum version
beforeCreate is called before the instance is initialized. See details
created is called immediately after the instance is created. See
beforeMount is called before the mount starts. See details
mounted Called after the instance is mounted. See details Note: It is not sure that all subcomponents are mounted here, if you need to perform operations after subcomponents are fully mounted Use $nextTickVue official document
beforeUpdate Called when the data is updated, before the virtual DOM is patched. See details Only supported by H5 platform
updated This hook is called after the virtual DOM has been re-rendered and patched due to data changes. See details Only supported by H5 platform
beforeDestroy Called before the instance is destroyed. At this step, the instance is still fully available. See details
destroyed Called when the Vue instance is destroyed. After calling, everything pointed to by the Vue instance will be unbound, all event listeners will be removed, and all child instances will be destroyed. See details

# page call interface

# getApp()

getApp() 函数用于获取当前应用实例,一般用于获取globalData。也可通过应用实例调用 App.vue methods 中定义的方法。

实例 Instance

const app = getApp()
console.log(app.globalData)
app.doSomething() // 调用 App.vue methods 中的 doSomething 方法

注意: Notice:

  • 不要在定义于 App() 内的函数中,或调用 App 前调用 getApp() ,可以通过 this.$scope 获取对应的app实例
  • Do not call getApp() in a function defined in App() or before calling App, you can get the corresponding app instance through this.$scope
  • 通过 getApp() 获取实例之后,不要私自调用生命周期函数。
  • After obtaining the instance through getApp(), do not call the life cycle function privately.
  • 当在首页nvue中使用getApp()不一定可以获取真正的App对象。对此提供了const app = getApp({allowDefault: true})用来获取原始的App对象,可以用来在首页对globalData等初始化
  • When you use getApp() in the home page nvue, you may not necessarily get the real App object. For this reason, const app = getApp({allowDefault: true}) is provided to obtain the original App object, which can be used to initialize globalData etc. on the homepage

# getCurrentPages()

getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,数组中的元素为页面实例,第一个元素为首页,最后一个元素为当前页面。

List of method properties for each page instance:

Methods Description Platform Description
page.$getAppWebview() Get the webview object instance of the current page App
page.route Get the route of the current page

注意:

getCurrentPages() 仅用于展示页面栈的情况,请勿修改页面栈,以免造成页面状态错误。
页面关闭时,对应页面实例会在页面栈中删除。

Tips:

  • navigateTo, redirectTo 只能打开非 tabBar 页面。
  • switchTab 只能打开 tabBar 页面。
  • `reLaunch`` 可以打开任意页面。
  • 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar
  • 不能在首页 onReady 之前进行页面跳转。

# $getAppWebview()

uni-appgetCurrentPages()获得的页面里内置了一个方法 $getAppWebview() 可以得到当前webview的对象实例,从而实现对 webview 更强大的控制。在 html5Plus 中,plus.webview具有强大的控制能力,可参考:WebviewObjectuni-app There is a built-in method $getAppWebview() in the page obtained by getCurrentPages(), which can get the object instance of the current webview, so as to realize the update of the webview. Powerful controls. In html5Plus, plus.webview has powerful control ability, please refer to: WebviewObject.

But the uni-app framework has its own window management mechanism, please do not create and destroy the webview yourself. If you need to cover the sub-form, please use native sub-form subNvue.

Note: This method is only supported by App

Example:

Get the object instance of the current page webview

export default {
  data() {
    return {
      title: 'Hello'
    }
  },
  onLoad() {
    // #ifdef APP-PLUS
    const currentWebview = this.$scope.$getAppWebview(); //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效
    currentWebview.setBounce({position:{top:'100px'},changeoffset:{top:'0px'}}); //动态重设bounce效果
    // #endif
  }
}

Get the object instance of the specified page webview

getCurrentPages() can get all page objects, and then according to the array, you can get the specified page webview object

var pages = getCurrentPages();
var page = pages[pages.length - 1];
// #ifdef APP-PLUS
var currentWebview = page.$getAppWebview();
console.log(currentWebview.id);//获得当前webview的id
console.log(currentWebview.isVisible());//查询当前webview是否可见
);
// #endif

The web-view component that comes with uni-app is a newly inserted sub-webview in the page. For the method of obtaining this object, see: https://ask.dcloud.net.cn/article/35036

# page communication

# uni.$emit(eventName,OBJECT)

Trigger a global custom event. Additional parameters are passed to the listener callback.

Attribute Type Describe
eventName String Event name
OBJECT Object Additional parameters carried by triggering events

Code example

	uni.$emit('update',{msg:'页面更新'})

# uni.$on(eventName,callback)

Listen to global custom events. Events can be triggered by uni.$emit, and the callback function receives all the additional parameters of the incoming event trigger function.

Attribute Type Describe
eventName String Event name
callback Function Event callback function

Code example

	uni.$on('update',function(data){
		console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
	})

# uni.$once(eventName,callback)

Listen to global custom events. Events can be triggered by uni.$emit, but only once. Remove the listener after the first trigger.

Attribute Type Describe
eventName String Event name
callback Function Event callback function

Code example

	uni.$once('update',function(data){
		console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
	})

# uni.$off([eventName, callback])

Remove the global custom event listener.

Attribute Type Describe
eventName Array<String> Event name
callback Function Event callback function

Tips

  • If no parameters are provided, remove all event listeners;
  • If only the event is provided, remove all listeners of the event;
  • If both event and callback are provided, only the listener of this callback will be removed;
  • The provided callback must be the same one as the callback of $on to remove the listener of this callback;

Code example

$emit, $on and $off are commonly used for cross-page and cross-component communication, and are placed on the same page for easy demonstration

	<template>
		<view class="content">
			<view class="data">
				<text>{{val}}</text>
			</view>
			<button type="primary" @click="comunicationOff">结束监听</button>
		</view>
	</template>

	<script>
		export default {
			data() {
				return {
					val: 0
				}
			},
			onLoad() {
				setInterval(()=>{
					uni.$emit('add', {
						data: 2
					})
				},1000)
				uni.$on('add', this.add)
			},
			methods: {
				comunicationOff() {
					uni.$off('add', this.add)
				},
				add(e) {
					this.val += e.data
				}
			}
		}
	</script>

	<style>
		.content {
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
		}

		.data {
			text-align: center;
			line-height: 40px;
			margin-top: 40px;
		}

		button {
			width: 200px;
			margin: 20px 0;
		}
	</style>

Precautions

  • The events triggered by uni.$emit, uni.$on, uni.$once and uni.$off are all at the App global level, spanning arbitrary component, page, nvue, vue, etc.
  • When using, remember to destroy event listening to in time, for example, uni.$on registered listening to in the page onLoad, uni.$off removed in the page onUnload, or one-off events that use uni.$once to listen to directly

Further reading:

# Routing

uni-app page routing is managed by the framework. Developers need to configure the path and page style of each routing page in pages.json. Similar to the applet configuring page routing in app.json. Therefore, the routing usage of uni-app is different from that of Vue Router. If you still want to use Vue Router to manage routing, you can search for [Vue-Router](https://ext.dcloud.net.cn /search?q=vue-router).

# Routing jump

uni-app has two ways to jump to page routing: use navigator component to jump, and call API to jump.

注意

页面返回时会自动关闭 loading 及 toast, modal 及 actionSheet 不会自动关闭。
页面关闭时,只是销毁了页面实例,未完成的网络请求、计时器等副作用需开发者自行处理。

# page stack

The framework manages all current pages in the form of stack. When a route switch occurs, the page stack behaves as follows:

Routing mode Page stack performance Trigger timing
Initialization Pushing a new page into the stack The first page opened by uni-app
Open a new page New page onto the stack Call API uni.navigateTo, use component <navigator open-type="navigate"/>
Page redirection The current page is out of the stack, and the new page is in the stack Call API uni.redirectTo, use component <navigator open-type="redirectTo"/>
Page return The page is constantly popped until the target returns to the page Call API uni.navigateBack , use component <navigator open-type="navigateBack"/>, user presses back button in the upper left corner, Android user presses back button
Tab switching All the pages are out of the stack, leaving only the new Tab page Call API uni.switchTab, use component <navigator open-type="switchTab"/>, user switches Tab
Reload All the pages are out of the stack, leaving only the new page Call API uni.reLaunch, Use component <navigator open-type="reLaunch"/>

# Page code specification introduction

uni-app 支持在 template 模板中嵌套 <template/><block/>,用来进行 条件渲染列表渲染

<template/> and <block/> is not a component, they are just a wrapper element that doesn't do any rendering on the page and only accepts control properties.

<block/> There are some differences in the performance of different platforms, it is recommended to use it uniformly<template/>.

Code example

<template>
	<view>
		<template v-if="test">
			<view>test 为 true 时显示</view>
		</template>
		<template v-else>
			<view>test 为 false 时显示</view>
		</template>
	</view>
</template>
<template>
	<view>
		<block v-for="(item,index) in list" :key="index">
			<view>{{item}} - {{index}}</view>
		</block>
	</view>
</template>

# Common differences between nvue development and vue development

Rendering based on native engines, although it is still a front-end technology stack, is definitely different from web development.

  1. Only v-if can be used to control the display and hide of nvue pages, not v-show
  2. nvue pages can only use flex layout, other layout methods are not supported. Before developing a page, first figure out what the vertical content of this page has, which ones are to be scrolled, and then what is arranged on the horizontal axis of each vertical content, and design the interface according to the flex layout.
  3. The layout direction of nvue pages is vertical (column) by default. To change the layout direction, you can go to manifest.json -> app-plus -> nvue -> flex-direction Modifications under the node only take effect in uni-app mode. Details.
  4. When the nvue page is compiled into H5 and applet, it will do a work of aligning the default value of css. Because the weex rendering engine only supports flex, and the default flex direction is vertical. On the other hand, H5 and applet, which use web rendering, are not flex by default, and after setting display:flex, their flex direction is horizontal instead of vertical by default. Therefore, when nvue is compiled into H5 and applet, it will automatically set the default layout of the page to flex and the direction to be vertical. Of course, the default settings will be overwritten by the developer after manual settings.
  5. The text content must and can only be in <text> under Components. cannot be in <div>,<view> Write text directly in thetext` area of ``. Otherwise, even if it is rendered, the variables in js cannot be bound.
  6. Only the text tag can set the font size and font color.
  7. Layouts cannot use percentages, no media queries.
  8. When nvue switches between landscape and portrait screens, it may cause style problems. It is recommended that pages with nvue lock the orientation of the phone.
  9. The supported css is limited, but it does not affect the layout of the interface you need. flex is still very powerful. See details
  10. Background images are not supported. But you can use the image component and hierarchy to achieve background effects similar to those in the web. Because native development itself does not have the concept of web background image
  11. CSS selectors are less supported, and only class selectors can be used. See details
  12. The components of nvue are transparent by default on the Android side. If background-color is not set, it may cause ghosting problems.
  13. class only supports array syntax when binding.
  14. Using a large number of rounded borders in a page on the Android side will cause performance problems, especially if the styles of multiple corners are not the same, it will cost more performance. Such use should be avoided.
  15. The nvue page has no bounce rebound effect, only a few list components have the bounce effect, including list, recycle-list, waterfall.
  16. There is no concept of page scrolling in native development. The page content will not scroll automatically if it is higher than the screen height. Only some components can be scrolled (list, waterfall, scroll-view/scroller). Sleeve under the rollable assembly. This is not in line with the habit of front-end development, so when nvue is compiled into uni-app mode, a scroller is automatically placed on the outer layer of the page, and the page content is too high and it will scroll automatically. (Components will not be nested, nor will they be nested when the page has a recycle-list). The configuration will be provided later, and it can be set to not automatically set.
  17. Global js variables defined in App.vue will not take effect on nvue pages. globalData and vuex are in effect.
  18. The global css defined in App.vue takes effect on both nvue and vue pages. If some CSS in the global CSS is not supported under nvue, the console will alarm when compiling. It is recommended to wrap these unsupported CSS in conditional compilation, APP-PLUS-NVUE
  19. The font file cannot be imported in style. Reference for the use of font icons in nvue: Load custom font. If it is a local font, you can use the plus.io API to convert the path.
  20. Currently using typescript/ts in nvue pages is not supported.
  21. When the nvue page closes the native navigation bar, if you want to simulate the status bar, you can refer to the article. However, it is still strongly recommended to use the native navigation bar in nvue pages. No matter how fast the rendering speed of nvue is, it is not as fast as the native navigation bar. It takes very little time for the native typesetting engine to parse json to draw the native navigation bar, but it takes much longer to parse the js of nvue to draw the entire page, especially when the new page enters the animation. For complex pages, there is no native navigation bar. Blank or flicker the entire screen during the animation.