uni-app分编译器和运行时(runtime)。uni-app能实现一套代码、多端运行,是通过这2部分配合完成的。
编译器支持条件编译,即可以指定某部分代码只编译到特定的终端平台。从而将公用和个性化融合在一个工程中。
运行时(runtime)包括3部分:基础框架、组件、API
基础框架:
- 包括语法、数据驱动、全局文件、应用管理、页面管理、js引擎、渲染和排版引擎等
- js引擎主要用于运行脚本
- 渲染引擎主要用于渲染页面,
.vue页面文件由webview渲染,原理与小程序相同;.nvue页面文件由原生渲染,原理与react native相同
组件:
- runtime中包括的组件只有基础组件,如
<view>、<button>等。扩展组件不包含在uni-app的runtime中,而是下载到用户的项目代码中。(这些组件都是vue组件)
API:
- uni-app runtime内置了大量常见的、跨端的 API,比如联网(uni.request)、读取存储(uni.getStorage)
- 同时uni-app不限制各端原生平台的API调用。开发者可以在uni-app框架中无限制的调用该平台所有能使用的API。
逻辑层和渲染层分离
在web平台,逻辑层(js)和渲染层(html、css),都运行在统一的webview里。
但在小程序和app端,逻辑层和渲染层被分离了。虽然开发者在一个 vue 页面里写 js 和 css,但其实,编译时就已经将它们拆分了。
jscore就是一个标准 js 引擎,标准 js 是可以正常运行的,比如 if、for、各种字符串、日期处理等。js 和浏览器的区别要注意区分开来。 `
- 所谓浏览器的 js 引擎,就是
jscore或v8的基础上新增了一批浏览器专用 API,比如 dom; - node.js 引擎,则是 v8 基础上补充一些电脑专用 API,比如本地 io;
- 那么 uni-app 的 App 端和小程序端的 js 引擎,其实是在
jscore上补充了一批手机端常用的 JS API,比如扫码。
uni-app 的 js 基本没有不同手机的兼容问题(因为 js 引擎自带了),而视图层的 css,在 app-vue 上使用系统 webview 时会有手机浏览器的 css 兼容问题。此时或者不要用太新的 css 语法,或者集成腾讯 x5 引擎。
逻辑层和视图层分离,好处是 js 运算不卡渲染,最简单直接的感受就是:窗体动画稳。但是两层分离也带来一个坏处,这两层互相通信,其实是有损耗的。
在 app-nvue 里,逻辑层和视图层的折损一样存在。包括 react native 也有这个问题。所以也千万别以为原生渲染就多么高级。
对于复杂页面,更新某个区域的数据时,需要把这个区域做成组件,这样更新数据时就只更新这个组件,否则会整个页面的数据更新,造成点击延迟卡顿。
app-nvue 和 h5 不存在此问题。造成差异的原因是小程序目前只提供了组件差量更新的机制,不能自动计算所有页面差量。
在 uni-app 中,定义在 data 里面的数据每次变化时都会通知视图层重新渲染页面。所以如果不是视图所需要的变量,可以不定义在 data 中,可在外部定义变量或直接挂载在 vue 实例上,以避免造成资源浪费。
长列表中每个 item 并不一定需要做成组件,取决于你的业务中是否需要差量更新某一行 item 的数据,如没有此类需求则不应该引入大量组件。(点击 item 后背景变色,属于 css 调整,没有更新 data 数据和渲染,不涉及这个问题)
多使用 css 动画,而不是通过 js 的定时器操作界面做动画
在 App 端 uni-app 的 nvue 页面可是基于 weex 升级改造的原生渲染引擎,实现了页面原生渲染能力、提高了页面流畅性。若对页面性能要求较高可以使用此方式开发
一、准备编辑器编译器Hbuilderx
app运行环境安装
真机运行的目的,是为了实现代码修改的热刷新,避免打包才能看到效果。在HBuilder中编辑代码,在手机上实时看到修改效果,并且可以在HBuilder控制台看到日志。
使用wifi无线连接真机
- 手机:Android 11(API 级别 30)或更高版本。TV/WearOS:Android 13(API 级别 33)或更高版本
- 确保电脑和设备连接同一WiFi网络
- 确保电脑端防火墙未禁止HBuilderX访问局域网络
模拟器调试
首先需要安装模拟器,我选择了安装安卓模拟器,国内可通过developer.android.google.cn/studio进行下载并…
二、创建uniappx项目
推荐使用Hbuilderx可视化界面创建,简单高效
选择创建uniappx项目,创建后,如果是uniappx项目,则在项目的manifest.json文件中会有以下标识:
"uni-app-x": {},
工程结构
最常用的几个目录有
1、pages
存储业务页面文件
2、static
存储静态资源,比如图片、视频等
3、nativeResources
app端原生资源目录
支持直接在应用项目中配置应用清单文件 AndroidManifest.xml 和资源目录 assets、res。AndroidManifest.xml的内容,和manifest.json的内容应避免冲突,即不配置manifest中已经配置过的内容。云端打包时应用清单文件会合并
uni-app x项目manifest.json中没有提供Android权限的配置,需在此AndroidManifest.xml中添加。
assets、res目录中的资源不能通过uni API使用,需通过 Android 原生 API 访问
4、uni_modules
类似于node_modules,提供uniapp的包管理方案,不管是js/uts库、组件、页面、uniCloud云函数、公共模块等的封装,甚至是整个项目,都可以封装成一个uni_modules
除了发布插件,uni_modules同时也是一种大型工程的模块分割方案。比如一个旅游应用,可以把机票、酒店、火车票、自由行等模块分拆成不同的uni_modules,由不同的部门来开发。
在uni_modules的utssdk目录,可以放置uts插件。
uts插件是非常重要的一种跨端插件。它支持API插件和组件插件,可通过原生能力,封装后给uni-app(x)扩展API和组件。
相比于uts插件,当然官方更推荐使用 uni_modules 方式,这是更好的包管理方案。
5、hybrid
App端存放web-view组件使用的本地html文件的目录
6、unpackage
非工程代码,一般存放运行或发行的编译结果、App自定义基座。
7、main.uts
vue的初始化入口文件。
8、App.uvue
应用配置,配置app全局样式及监听
9、pages.json
配置页面路由、导航条、选项卡等页面类信息
10、uni.scss
内置的常用样式变量, 这里是uni-app内置的常用样式变量, uni-app 官方扩展插件及插件市场上很多三方插件均使用了这些样式变量
pages(业务页面存放目录)
uni-app x 只有 .uvue页面,不支持和vue页面并存(因vue是js驱动、webview渲染,uni-app x在app-Android中没有js引擎,app中渲染是原生渲染,无法使用vue页面)。
每次新建页面,均需在pages.json中配置pages列表;未在pages.json -> pages 中注册的页面,在编译阶段会被忽略,不会进入编译产物。
pages.json中配置的pages数组中第一项表示应用启动页
运行时每个打开的页面,都有一个UniPage实例。
在 Vue 中,页面也是一种组件,所以也同时支持组件生命周期。
pages.json中页面的style中各个设置是最早生效的,原生导航栏、页面背景色都会立即生效。
除了管理页面,pages.json支持对页面进行特殊配置,比如应用首页的tabbar、每个页面的顶部导航栏设置。
可以在pages.json中配置globalStyle、tabBar等
无法使用vue-router,路由须在pages.json中进行配置。
main.uts(uvue的入口)
main.js主要作用是初始化vue实例、定义全局组件、使用需要的插件如 i18n、vuex。
一般情况下,使用easycom比全局组件更常用,easycom按需应用更节省资源。
开发者写的代码,在应用启动时,按如下时序加载:
- main.js/uts 的
export function createApp() {}外的代码、任何页面/组件的script中export default {}外的代码 - main.js/uts 的
export function createApp() {}中的代码 - app.vue/uvue中onLaunch的代码
- 首页的onLoad
- 首页的onReady
开发者需谨慎在main.js/uts、页面/组件script中export default {}外、和onLaunch中编写代码
App.uvue
App.uvue是uni-app-x的主组件。
所有页面都是在App.uvue下进行切换的,是应用入口文件。但App.uvue本身不是页面,这里不能编写视图元素,也就是没有<template>。
这个文件的作用包括:
- 监听应用生命周期
- 配置全局变量globalData
- 编写全局可用的method方法
- 配置全局样式
应用生命周期仅可在App.uvue中监听,在页面监听无效。
App.uvue仅支持选项式,暂不支持组合式写法。
在App.uvue中可以定义全局方法、全局变量、全局样式
全局变量与状态管理
uni-app x 在app平台暂不支持 pinia 和 vuex。可通过 globalData 或一个专用模块组织和管理全局变量与状态。
- 定义一个模块,编写一个单独的uts文件,比如 /store/index.uts,在里面设一个全局变量
- 在需要的页面和uts文件里,import上面的/store/index.uts
- 不管在哪里修改了globalNum的值,界面上都会自动更新。
uni.scss
可以配置样式的地方包括:theme.json、pages.json、App.uvue、uni.scss、业务页面
uni.scss是一个特殊文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的编译器在webpack配置中特殊处理了这个uni.scss,使得每个scss文件都被注入这个uni.scss,达到全局可用的效果。
注意:
- 如要使用这些常用变量,需要在 HBuilderX 里面安装 scss 插件;
- 使用时需要在 style 节点上加上
lang="scss"。 - pages.json不支持scss,原生导航栏和tabbar的动态修改只能使用js api
theme.json
theme.json,用于解决pages.json的主题适配问题。
在页面的onLoad中设置当前页面的style会来不及,小程序提供了theme.json来给解决这个问题。在theme.json里配置light和dark的颜色,然后在pages.json中引用。
新页面创建时是根据pages.json的设置来初始化页面的,这样就可以在第一时间对页面样式进行适配,避免闪白闪黑。
但需要注意:theme.json,仅负责pages.json的页面样式、tabbar样式的控制。不负责开发者自己的页面css样式控制。
考虑到全端兼容,uni-app x的web和app也支持theme.json设置。
- 在项目根目录下创建theme.json
- 在
theme.json中定义相关变量 - 在
pages.json中以@开头引用变量 - 可选在
manifest.json -> app中配置主题默认值"defaultAppTheme": "light", 支持通过主题API动态设置
三、组件的使用
- 组件是视图层的基本组成单元。
- 组件是一个单独且可复用的UI及配套功能模块的封装。
- 所有组件,都写在template标签下面。
我们知道js逻辑可以封装为函数或类库。而对于页面上可视的元素,则可以将ui、样式、逻辑一起封装为组件。
组件涉及较多的概念,包括组件名称、开头和闭合标签、组件属性、组件属性值、组件事件、组件vue指令、组件text内容、子组件。
v-bind绑定后属性值的内容变成了script,而不再是普通字符串。所以在属性值里写字符串需要再加单引号。
uni-app x有一批标准组件,同时也支持扩展自定义组件。
内置组件 内置在uni-app x引擎中,开发者无需在代码中引用和注册的,可以直接使用。比如view、text、button
自定义组件,这类组件需要手动下载到项目中,或者自行在项目下编写。
自定义组件,按开发方式分类,又有2种:前端uvue组件 和 原生uts组件
uts原生组件,下载组件到项目后(或自己按规范编写),在页面template里直接引用即可。无需导入注册组件。
对于前端uvue组件,又有2种引用方式。
- 传统vue组件: 需要先import、注册,然后再在页面template中使用。
- easycom组件 easycom组件是uni-app提供的一种易用方式,它通过一个路径规范让编译器知道组件的位置,实现自动的import和注册。
在uni插件市场(ext.dcloud.net.cn/),下载的组件基本都是…
四、打包发行
标准基座使用的图标、包名、证书以及配置的三方sdk的appkey等各种原生信息,都是DCloud的。
当需要使用自己的包名、证书、原生配置以及变更三方原生sdk时,需在打包界面勾选打包自定义基座,打包后的自定义基座会放置在项目的unpackage目录下,然后在运行项目时的界面中可以选择自定义基座来运行
所有平台的都支持本地发行,同时依赖本地安装的发布环境。在菜单或弹出界面上有相应的教程链接。
如果发布Android和iOS应用,HBuilder还额外提供了方便的云打包,免去安装和配置原生环境,直接出apk、ipa包。