uni-app的目录结构、页面的创建和删除、页面的生命周期和组建的生命周期、页面通信、路由、

1,942 阅读9分钟

# 开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第30天,点击查看活动详情

目录结构

一个uni-app工程,默认包含如下目录及文件

image.png

页面

  1. 页面的创建和删除
  2. 页面的生命周期
  3. 组件的生命周期
  4. getApp()函数用于获取当前应用实例,一般用于获取globalData 。
  5. getCurrentPages():函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面

新建页面

uni-app中的页面,通常会保存在工程根目录下的pages目录下。 每次新建页面,均须在pages.json中配置pages列表,未在pages.json->pages中配置的页面,uni-app会在编一阶段进行忽略。
通过HBuilderX 开发uni-app项目时,在uni-app项目上右键“新建页面”,HBuilderX会自动在pages.json中完成页面注册,开发更方便。

image.png

删除页面

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

  • 删除.vue文件或.nvue文件
  • 删除pages.json -> pages列表项中的配置

应用首页

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

[#]页面生命周期

image.png

  1. onInit:监听页面初始化,其参数同onLoad参数,为上个页面传递的数据,参数类型为Object(用于页面传参),触发时机早于onLoad,针对于百度小程序的
  2. onLoad:监听页面加载,其参数为上个页面传递的数据,参数类型为Object(用于页面传参)

组件的生命周期

image.png

全局文件 App.vue

App.vue是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素,也就是没有<template>(相当于微信小程序的app.js) 这个文件的作用包括:调用应用生命周期函数、配置全局样式、配置全局的存储globalData

应用生命周期仅可在App.vue中监听,在页面监听无效。

[#]应用生命周期

image.png

image.png 注意

  • 应用生命周期仅可在App.vue中监听,在其它页面监听无效
  • 应用启动参数,可以在API uni.getLaunchOptionsSync获取
  • onlaunch里进行页面跳转,如遇白屏报错,请参考ask.dcloud.net.cn/article/359…
  • App.vue 不能写模板
  • onPageNotFound 页面实际上已经打开了(比如通过分享卡片、小程序码)且发现页面不存在,才会触发,api 跳转不存在的页面不会触发(如 uni.navigateTo

全局变量globalData

在App.vue中配置全局的globalData,在需要的组件内通过getApp().globalData.具体属性名,进行获取。通过this.状态名可以进行赋值修改。 image.png

页面通信

uni.$emit(eventName,OBJECT):触发全局的自定义事件。附加参数都会传给监听器回调

image.png

image.png
uni.on(eventName,callback):监听全局的自定义事件。事件可以由uni.on(eventName,callback):监听全局的自定义事件。事件可以由 uni.emit 触发,回调函数会接收所有传入事件触发函数的额外参数

image.png

image.png
示例代码:

image.png

image.png
uni.once(eventName,callback):监听全局的自定义事件。事件可以由uni.once(eventName,callback):监听全局的自定义事件。事件可以由 uni.emit 触发,但是只触发一次,在第一次触发之后移除监听器。

image.png

image.png
uni.$off([eventName,callback]):移除全局自定义事件监听器。

image.png
Tips

  • 如果没有提供参数,则移除所有的事件监听器;
  • 如果只提供了事件,则移除该事件所有的监听器;
  • 如果同时提供了事件与回调,则只移除这个回调的监听器;
  • 提供的回调必须跟$on的回调为同一个才能移除这个回调的监听器;

代码示例

$emit$on$off常用于跨页面、跨组件通讯,这里为了方便演示放在同一个页面

image.png
注意事项

  • uni.emituni.emit、 uni.on 、 uni.onceuni.once 、uni.off 触发的事件都是 App 全局级别的,跨任意组件,页面,nvue,vue 等
  • 使用时,注意及时销毁事件监听,比如,页面 onLoad 里边 uni.on注册监听,onUnload里边uni.on 注册监听,onUnload 里边 uni.off 移除,或者一次性的事件,直接使用 uni.$once 监听

路由

uni-app页面路由为框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在 app.json 中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同,如仍希望采用 Vue Router 方式管理路由,可在插件市场搜索 [Vue-Router]。

[#]路由跳转

uni-app 有两种页面路由跳转方式:使用[navigator]组件跳转、调用[API]跳转

页面栈

框架以栈的形式管理当前所有页面, 当发生路由切换的时候,页面栈的表现如下:

image.png

页面代码规范介绍

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

<template/> 和 <block/> 并不是一个组件,它们仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

<block/> 在不同的平台表现存在一定差异,推荐统一使用 <template/>

image.png

image.png

nvue 开发与 vue 开发的常见区别

基于原生引擎的渲染,虽然还是前端技术栈,但和 web 开发肯定是有区别的。

  1. nvue 页面控制显隐只可以使用v-if不可以使用v-show
  2. nvue 页面只能使用flex布局,不支持其他布局方式。页面开发前,首先想清楚这个页面的纵向内容有什么,哪些是要滚动的,然后每个纵向内容的横轴排布有什么,按 flex 布局设计好界面。
  3. nvue 页面的布局排列方向默认为竖排(column),如需改变布局方向,可以在 manifest.json -> app-plus -> nvue -> flex-direction 节点下修改,仅在 uni-app 模式下生效。[详情]。
  4. nvue 页面编译为 H5、小程序时,会做一件 css 默认值对齐的工作。因为 weex 渲染引擎只支持 flex,并且默认 flex 方向是垂直。而 H5 和小程序端,使用 web 渲染,默认不是 flex,并且设置display:flex后,它的 flex 方向默认是水平而不是垂直的。所以 nvue 编译为 H5、小程序时,会自动把页面默认布局设为 flex、方向为垂直。当然开发者手动设置后会覆盖默认设置。
  5. 文字内容,必须、只能在<text>组件下。不能在<div><view>text区域里直接写文字。否则即使渲染了,也无法绑定 js 里的变量。
  6. 只有text标签可以设置字体大小,字体颜色。
  7. 布局不能使用百分比、没有媒体查询。
  8. nvue 切换横竖屏时可能导致样式出现问题,建议有 nvue 的页面锁定手机方向。
  9. 支持的 css 有限,不过并不影响布局出你需要的界面,flex还是非常强大的。[详见]
  10. 不支持背景图。但可以使用image组件和层级来实现类似 web 中的背景效果。因为原生开发本身也没有 web 这种背景图概念
  11. css 选择器支持的比较少,只能使用 class 选择器。[详见]
  12. nvue 的各组件在安卓端默认是透明的,如果不设置background-color,可能会导致出现重影的问题。
  13. class 进行绑定时只支持数组语法。
  14. Android 端在一个页面内使用大量圆角边框会造成性能问题,尤其是多个角的样式还不一样的话更耗费性能。应避免这类使用。
  15. nvue 页面没有bounce回弹效果,只有几个列表组件有bounce效果,包括 listrecycle-listwaterfall
  16. 原生开发没有页面滚动的概念,页面内容高过屏幕高度并不会自动滚动,只有部分组件可滚动(listwaterfallscroll-view/scroller),要滚得内容需要套在可滚动组件下。这不符合前端开发的习惯,所以在 nvue 编译为 uni-app 模式时,给页面外层自动套了一个 scroller,页面内容过高会自动滚动。(组件不会套,页面有recycle-list时也不会套)。后续会提供配置,可以设置不自动套。
  17. 在 App.vue 中定义的全局 js 变量不会在 nvue 页面生效。globalDatavuex是生效的。
  18. App.vue 中定义的全局 css,对 nvue 和 vue 页面同时生效。如果全局 css 中有些 css 在 nvue 下不支持,编译时控制台会报警,建议把这些不支持的 css 包裹在[条件编译]里,APP-PLUS-NVUE
  19. 不能在 style 中引入字体文件,nvue 中字体图标的使用参考:[加载自定义字体]。如果是本地字体,可以用plus.io的 API 转换路径。
  20. 目前不支持在 nvue 页面使用 typescript/ts
  21. nvue 页面关闭原生导航栏时,想要模拟状态栏,可以[参考文章]。但是,仍然强烈建议在 nvue 页面使用原生导航栏。nvue 的渲染速度再快,也没有原生导航栏快。原生排版引擎解析json绘制原生导航栏耗时很少,而解析 nvue 的 js 绘制整个页面的耗时要大的多,尤其在新页面进入动画期间,对于复杂页面,没有原生导航栏会在动画期间产生整个屏幕的白屏或闪屏。

全局文件

pages.json页面路由

pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等。

它类似微信小程序中app.json页面管理部分。注意定位权限申请等原属于app.json的内容,在uni-app中是在manifest中配置。

配置项列表

image.png 以下是一个包含了所有配置选项的 pages.json :

image.png

globalStyle

用于设置应用的状态栏、导航条、标题、窗口背景色等

image.png

topWindow

uni-app 2.9+ 新增 leftWindow, topWindow, rightWindow 配置。用于解决宽屏适配问题。

以现有的手机应用为mainWindow,在左、上、右,可以追加新的页面显示窗体。

整体的宽屏适配思路,参考单独的[宽屏适配指南]

image.png 注意

  • 目前 style 节点仅支持配置 width,height 等 css 样式相关属性

  • 如果需求当存在 topwindow 时,自动隐藏页面的 navigationBar,根据需求不同在App.vue中配置如下 css:

    • 只需要隐藏某个的页面 navigationBar

image.png - 需要隐藏大部分页面的 navigationBar,显示某个页面的 navigationBar

image.png

matchMedia

image.png 通过matchMedia的调节,可以自适应在不同屏幕上显示指定的window。

image.png

pages

uni-app 通过 pages 节点配置应用由哪些页面组成,pages 节点接收一个数组,数组每个项都是一个对象,其属性值如下

image.png Tips:

  • pages节点的第一项为应用入口页(即首页)
  • 应用中新增/减少页面,都需要对 pages 数组进行修改
  • 文件名不需要写后缀,框架会自动寻找路径下的页面资源
h5

配置编译到H5平台时的特定样式 image.png

  • 导航栏

image.png

  • 自定义按钮

image.png

  • 按钮样式:使用 type 值设置按钮的样式时,会忽略 fontSrc 和 text 属性。

image.png

  • 下拉刷新:h5 平台下拉刷新动画,只有 circle 类型。

image.png

  • 搜索框样式

image.png 注意事项:

  • 如果 h5 节点没有配置,默认会使用 app-plus 下的配置。
  • 配置了 h5 节点,则会覆盖 app-plus 下的配置
    示例代码:

image.png