笔记内容主要参考uni-app官方文档,仔细阅读uni-app官方文档 介绍教程等部分能获得更多内容。

什么是uni-app

是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程快应用等多个平台。

uni-app的由来:uni-app官网

HBuilderX

HBuilderX是通用的前端开发工具,但为uni-app做了特别强化,和uni-app属于同一家公司的产品。

基本配置

  • 插件下载:工具->插件下载
  • 快捷方式定制:工具->预定快捷方案
  • tab补全代码:工具->设置->语言服务配置
  • 保存代码格式化:工具->设置->编辑器配置
  • 合并代码时显示最后一行代码:工具->设置->编辑器配置

创建一个uni-app项目

在点击工具栏里的文件 -> 新建 -> 项目

选择uni-app类型,输入工程名,选择模板,点击创建,即可成功创建。

uni-app自带的模板有默认的空项目模板、Hello uni-app 官方组件和API示例,还有一个重要模板是 uni ui项目模板,日常开发推荐使用该模板,已内置大量常用组件。

也可以使用vue-cli命令行开发,不过个人还是喜欢使用HBuilder。

运行uni-app

点击左上角的运行选项,即可选择项目的运行方式

如果要运行到手机,需要连接usb,在设置中开启USB调试。如果要运行到手机模拟器,则需要先下载,比如逍遥,雷电模拟器,然后打开这些应用,才能被hbuilder检测到。

将项目运行到微信开发者工具

  • AppID

    manifest->微信小程序配置中填写自己的微信小程序的 AppID,这个是需要我们去申请的

  • 安装路径

    设置中配置“微信开发者工具”的安装路径,只有配置了微信开发者工具路径,hx才能打开微信开发者工具

  • 开启服务端口

    在微信开发者工具中,通过 设置 -> 安全设置面板,开启微信开发者工具的服务端口

发布uni-app

打包为原生App

在打包之前也需要在manifest.json 的可视化界面做相关配置。

  • 在基础配置面板中,获取uni-app 应用标识,并填写应用名称
  • 切换到 App 图标配置面板,点击浏览按钮,选择合适的图片之后,再点击自动生成所有图标并替换

在HBuilderX工具栏,点击发行,选择原生app-云端打包(在线打包),云端打包支持安心打包,保护用户隐私,不会上传代码和证书,通过差量包制作方式实现安心打包,缺点是可能需要排队。云打包完成后,在内置控制台点击链接下载 apk 的安装包,并安装到 Android 手机中查看打包的效果。

虽然安心打包已经满足需求,但如仍然希望自己使用 xcode 或 Android studio 进行离线打包,则在 HBuilderX 发行菜单里找到本地打包菜单,生成离线打包资源,然后参考离线打包文档操作:https://nativesupport.dcloud.net.cn/AppDocs/README

App打包时,注意如果涉及三方sdk,需进行申请并在manifest.json里配置,否则相关功能无法使用。

iOS App打包需要向Apple申请证书

发布为Web网站

manifest.json 的可视化界面,进行如下配置

如果使用history路由,就需要后端服务器做对应的配置,具体原因参考前端面试—vue部分 | 三叶的博客中前端路由部分。

当我们令运行时的基础路径为/api/,打包后index.html引入文件的路径就会变成如下:

1
2
 <script type="module" crossorigin src="/api/assets/index-yJj5sN9l.js"></script>
<link rel="stylesheet" crossorigin href="/api/assets/index-Dl1z_jWj.css">

在HBuilderX工具栏,点击发行,选择网站-H5,点击会弹出这个窗口:

无需在意,直接点击发行,即可生成 H5 的相关资源文件,保存于unpackage/dist/build/web 目录。

至于部署打包后的网页,其实和部署博客一样,可以借助github-pages+vercel,或者使用dcloud免费的网页托管服务。

发布为微信小程序

  1. 申请微信小程序AppID,参考:微信教程

  2. 在HBuilderX中顶部菜单依次点击 “发行” => “小程序-微信”,输入小程序名称和appid点击发行即可

如果手动发行(未勾选自动上传微信平台),则点击发行按钮后,会在项目的目录 unpackage/dist/build/mp-weixin 生成微信小程序项目代码。打开微信小程序开发者工具,导入生成的微信小程序项目,测试项目代码运行正常后,点击上传按钮,之后按照 提交审核=> 发布小程序标准流程,逐步操作即可,详细查看:微信官方教程

如果在发行界面勾选了自动上传微信平台,则无需再打开微信工具手动操作,将直接上传到微信服务器提交审核。

项目结构

下面只展示基础的项目结构,更详细的结构可以参考官方文档。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
│─components            符合vue组件规范的uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源都应存放于此目录
├─uni_modules 存放uni_module 详见
├─unpackage 非工程代码,一般存放运行或发行的编译结果
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见
└─uni.scss 内置的常用样式变量

微信小程序中的一个页面就是一个文件夹,然后里面有四个文件,分别对应html,css,js,json文件,而在uni-app中,一个vue文件就包含了前三者,然后页面json文件被page.json中的pages.style属性给替代了。

page.json

项目页面的配置文件 ,类似微信小程序中的app.json,这种命名方式貌似着重强调了pages属性。

主要组成:

  • globalStyles:全局定义页面的样式,会被pages中页面单独定义的样式覆盖

    1
    2
    3
    4
    5
    6
    "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarBackgroundColor": "#fff",
    "backgroundColor": "#F8F8F8"
    // "navigationStyle": "custom"
    },

    可以看出,page.json文件中的globalStyles属性替换了微信小程序中的app.json文件中的window属性

  • pages:注册页面的地方;值是一个数组,数组元素是一个一个的页面对象,第一个页面对象就是首屏,这些页面都会被打包进主包

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    {
    "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
    {
    "path": "pages/home/home",
    "style": {
    "navigationBarTitleText": "推荐",
    "navigationStyle": "custom",
    "enablePullDownRefresh": true
    }
    },
    {
    "path": "pages/classify/classify",
    "style": {
    "navigationBarTitleText": "分类",
    "navigationStyle": "custom",
    "enablePullDownRefresh": true
    }
    }
    ]
    }

    页面对象属性:

    • path:页面组件路径
    • style:定义页面的一些样式,比如配置,"navigationStyle": "custom";配置后这个页面的导航栏直接消失了

    可以注意到page.json中的pages的style属性其实就是替换掉了微信小程序中页面的json文件

  • tabbar:值是一个对象,用来配置标签栏,和app.json中的语法相同。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    {
    "tabBar": {
    "selectedColor": "#28b389",
    "list": [{
    "pagePath": "pages/home/home",
    "iconPath": "static/home.png",
    "selectedIconPath": "static/home-h.png",
    "text": "推荐"
    },
    {
    "pagePath": "pages/classify/classify",
    "iconPath": "static/classify.png",
    "selectedIconPath": "static/classify-h.png",
    "text": "分类"
    },
    {
    "pagePath": "pages/user/user",
    "iconPath": "static/user.png",
    "selectedIconPath": "static/user-h.png",
    "text": "我的"
    }
    ]
    }
    }
  • subPackages:用来注册分包,属性的值是一个数组,数组的值是一个一个分包对象,有几个分包对象最终就有几个分包,这个属性的语法也和wx小程序的app.json相同。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "subPackages": [
    {
    "root": "subpkg",
    "name":'pkgA',//分包别名
    //当前分包下所有页面的相对路径
    "pages": [
    "detail/detail",
    "goods_list/goods_list",
    "search/search"
    ]
    }
    ]
    }

更多内容参考:pages.json 页面路由 | uni-app官网

static目录

uni-app编译器根据pages.json扫描需要编译的页面,并根据页面引入的js、css合并打包文件。

对于本地的图片、字体、视频、文件等资源,如果可以直接识别,那么也会把这些资源文件打包进去,但如果这些资源以变量的方式引用, 比如:<image :src="url"></image>,甚至可能有更复杂的函数计算,此时编译器无法分析。

那么有了static目录,编译器就会把这个目录整体复制到最终编译包内,样只要运行时确实能获取到这个图片,就可以显示。

当然这也带来一个注意事项,如果static里有一些没有使用的废文件,也会被打包到编译包里,造成体积变大。

static 目录下的文件(vue组件、js、css 等)只有被引用时,才会被打包编译。

简单的来说就是,static目录下的文件无论是否被引用,都会被打包进最终文件,而非static目录下的文件,只有被引用了,才会被打包进最终文件。

uni.scss

uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量

1
2
3
4
5
6
7
....
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
.....

uni.scss是一个特殊文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的编译器在webpack配置中特殊处理了这个uni.scss,使得每个scss文件都被注入这个uni.scss,达到全局可用的效果。

简单来说,这就是一个只包含scss变量的文件,会被自动注入到所有scss文件中。

注意:

  1. 如要使用这些常用变量,需要在 HBuilderX 里面安装 scss 插件;
  2. 使用时需要在 style 节点上加上 lang="scss"
  3. pages.json不支持scss,原生导航栏和tabbar的动态修改只能使用js api

main.js

是 uni-app 的入口文件,类似微信小程序中的app.js文件。

main.js主要作用是:

  • 初始化vue实例
  • 定义全局组件
  • 使用需要的插件如 i18n、vuex。

说白了不就是和vue的入口文件作用一样吗,只不过在语法上略有区别。

1
2
3
4
5
6
7
8
9
10
11
12
13
//vue2
import Vue from 'vue'
import App from './App'
import PageHead from './components/page-head.vue' //全局引用 page-head 组件

Vue.config.productionTip = false
Vue.component('page-head', PageHead) //全局注册 page-head 组件,每个页面将可以直接使用该组件
App.mpType = 'app'

const app = new Vue({
...App
})
app.$mount() //挂载 Vue 实例

App.vue

所有页面都是在App.vue下进行切换的,是应用入口文件。但App.vue本身不是页面,这里不能编写视图元素,也就是

没有<template>

而在标准的 Vue.js 项目中,App.vue 通常作为应用的根组件,并且包含 <template><script><style> 标签。

而在 uni-app 中,App.vue 主要扮演的是一个全局配置文件(沦落至此)的角色,而不是具体的页面组件。在uni-app中的作用包括:监听应用生命周期、配置全局样式。我们可能有疑问,全局样式配置不是在uni.scss文件中进行的吗?其实不是哈,我们之前也介绍过,这个文件内部只是一些scss变量,很遗憾,这个文件虽然也在项目根目录,但并不像微信小程序中的app.wxss文件一样,用来书写全局样式。

应用生命周期仅可在App.vue中监听,在页面监听无效。至此,uni-app中的生命周期就包括了:组件的生命周期,页面的生命周期和应用的生命周期。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>

<style lang="scss">
/*每个页面公共css */
@import "@/common/styles/common.scss";
@import "@/uni.scss";
</style>

至于应用的生命周期有哪些:

函数名说明
onLaunchuni-app 初始化完成时触发(全局只触发一次),参数为应用启动参数,同 uni.getLaunchOptionsSync 的返回值
onShowuni-app 启动,或从后台进入前台显示,参数为应用启动参数,同 uni.getLaunchOptionsSync 的返回值
onHideuni-app 从前台进入后台
onErroruni-app 报错时触发
onUniNViewMessagenvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯
onUnhandledRejection对未处理的 Promise 拒绝事件监听函数(2.8.1+ app-uvue 暂不支持)
onPageNotFound页面不存在监听函数
onThemeChange监听系统主题变化
onLastPageBackPress最后一个页面按下Android back键,常用于自定义退出
onExit监听应用退出

页面

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

nvue

nVue(Native Vue)是由 DCloud 公司开发的一个用于构建原生移动应用的框架。它允许开发者使用 Vue.js 语法来编写代码,但最终生成的是真正的原生 UI 组件,而不是 WebView 中的网页。

weex

Weex 是由阿里巴巴集团开发的一个跨平台 UI 开发框架,它允许开发者使用 Web 技术(如 HTML、CSS 和 JavaScript)来编写一次代码,并将其部署到多个平台,包括 iOS、Android 和 Web。Weex 的设计理念是“Write Once, Run Everywhere”,即编写一次代码,到处运行,这使得它可以成为构建高效、可维护的跨平台应用的理想选择。

性能优化

Weex 生成的是原生组件而不是基于WebView的渲染,因此它提供了接近原生应用的性能表现。它也通过将 js逻辑原生渲染引擎分离,实现了高效的更新机制。

Weex 的 js引擎是在基础 js引擎(如 JavaScriptCore 或 V8)的基础上进行了扩展,以支持特定的 API 和功能。

对vue开发者友好

Weex 使用了类似于 Vue.js 的模板语法和组件化开发模式,对于熟悉 Vue.js 的开发者来说非常友好。此外,Weex 还可以直接集成 Vue.js 的生态系统工具链,如 Vue CLI 和 Vuex 等,但是现在很少直接使用weex开发的了。

缺点

Weex 提供了一套基础的 API 来访问设备功能,但这些 API 并没有涵盖所有可能的设备功能第三方服务集成需求

为了解决这些问题,一些团队选择扩展 Weex 的功能集,或者转向其他提供更广泛 API 支持的框架,如 React NativeFlutter。此外,DCloud 的nVue框架通过增强对原生 API 的支持,解决了 Weex 在这方面的一些局限性,使前端工程师能够更加独立地开发完整应用程序。

nvue如何实现原生渲染?

uni-appApp 端内置了一个基于 weex 改进的原生渲染引擎,提供了原生渲染能力。

以往的 weex ,有个很大的问题是它只是一个高性能的渲染器,没有足够的 API 能力(比如各种 push sdk 集成、蓝牙等能力调用),使得开发时非常依赖原生工程师协作,而nvue 解决了这个问题,让前端工程师可以直接开发完整 App,并提供丰富的插件生态和云打包

同时uni-app扩展了 weex 原生渲染引擎的很多排版能力,修复了很多 bug。

一个 App 中可以同时使用两种页面,比如首页使用 nvue,二级页使用 vue 页面,hello uni-app 示例就是如此。

具体步骤:

编译时

  1. 代码转换,资源打包

    • uni-app 使用其编译工具将Vue组件、样式和 JavaScript 逻辑转换为适合 iOS 或者 Android 平台的格式。

    • 对于 UI 部分,Vue 组件被映射到相应的原生控件。例如,一个 <button> 元素会被转换成 iOS 上的 UIButton 或 Android 上的 Button 控件。

    • 包括图片、字体等静态资源也会被打包进最终的应用程序。

    • 编译器还会优化这些资源以减少应用程序的体积并提高加载速度

    • 这两个过程都是基于 Webpack 或 Vite 来实现的。

  2. 生成原生项目结构

    • 编译后的代码文件会被组织成结构规范的项目
    • 这个过程中会集成必要的依赖库和服务,如 JavaScript 引擎(V8 或 JavaScriptCore)、通信桥梁等
  3. API 和组件注册

  • 编译器确保所有使用的 API 和自定义组件都被正确地注册和配置,以便在运行时可以正常工作。

运行时

用户安装并启动应用程序后,进入运行时阶段(此时原生渲染真正开始发挥作用)

JavaScript 引擎初始化

  • 应用程序启动时,首先会初始化 JavaScript 引擎(如 V8 或 JavaScriptCore),准备执行业务逻辑代码

UI 渲染

  • 根据编译时生成的映射关系,JavaScript 引擎与原生渲染引擎协作,动态创建和管理 UI 组件。
  • 每次视图更新或状态变化时,JavaScript 逻辑会通过通信桥梁告知原生层进行相应的 UI 更新。

事件处理和数据绑定

  • 用户交互产生的事件(如点击按钮)会被捕获,并通过通信桥梁传递给 JavaScript 层进行处理。
  • 数据绑定机制确保了模型数据的变化能够实时反映在界面上,反之亦然。

调用原生功能

  • 如果应用需要访问设备硬件或操作系统服务(如相机、地理位置),则通过预先定义好的 API 或插件来调用原生功能。

应用场景

虽然 nvue 也可以多端编译,输出 H5 和小程序,但 nvue 的 css 写法受限所以如果你不开发 App,那么不需要使用 nvue。

如果你熟悉 weex 或 react native 开发,那么开发app时, nvue 是你的更优选择,能切实提升你的开发效率,降低成本。

如果你是 web 前端,不熟悉原生排版,那么建议你仍然以使用 vue 页面为主,在 App 端某些 vue 页面表现不佳的场景下使用 nvue 作为强化补充。这些场景在官方文档中有介绍,太多了就不写了。

快速上手

  • 新建 nvue 页面

    在 HBuilderX 的 uni-app 项目中,新建页面,弹出界面右上角可以选择是建立vue页面还是nvue页面,或者 2 个同时建。

    不管是 vue 页面还是 nvue 页面,都需要在pages.json中注册。如果在 HBuilderX 中新建页面是会自动注册的,如果使用其他编辑器,则需要自行在 pages.json 里注册。

  • 开发 nvue 页面

    nvue 页面结构同 vue, 由 templatestylescript 构成。

更多内容参考:nvue介绍 | uni-app官网

新建页面

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

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

通过HBuilderX开发 uni-app 项目时,在 uni-app 项目上右键新建页面,HBuilderX会自动pages.json中完成页面注册,开发更方便。

同时,HBuilderX 还内置了常用的页面模板(如图文列表、商品列表等,区别于之前提到的项目模板),选择这些模板,可以大幅提升你的开发效率。

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

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

  • 如果只有一个页面文件,大可不必多放一层目录。

删除页面

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

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

页面改名

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

页面文件结构分析

页面文件结构就是vue文件呗,学过vue的都比较熟悉了。

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

  • 模板组件区 <template>
  • 脚本区 <script>
  • 样式区 <style>

页面生命周期

uni-app 页面除支持 Vue 组件生命周期外还支持下方页面生命周期函数(节选),其实无论组件还是页面,都是vue文件。

当以组合式 API 使用时,在 Vue2 和 Vue3 中存在一定区别。如果使用的是vue3语法,这些uni-app页面独有的生命周期函数使用前也要按需导入。

函数名说明
onInit监听页面初始化,其参数同 onLoad 参数,为上个页面传递的数据,参数类型为 Object(用于页面传参),触发时机早于 onLoad,只存在于百度小程序。
onLoad监听页面加载,该钩子被调用时,响应式数据、计算属性、方法、侦听器、props、slots 已设置完成,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例
onShow监听页面显示,页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
onReady监听页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用,注意如果渲染速度快,会在页面进入动画完成前触发
onHide监听页面隐藏
onUnload监听页面卸载
onResize监听窗口尺寸变化
onPullDownRefresh监听用户下拉动作,一般用于下拉刷新
onReachBottom页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。具体见下方注意事项
onTabItemTap点击 tab 时触发,参数为Object,具体见下方注意事项
onShareAppMessage用户点击右上角分享
onPageScroll监听页面滚动,参数为Object
onShareTimeline监听用户点击右上角转发到朋友圈
onAddToFavorites监听用户点击右上角收藏

页面生命周期,说白了就是页面会自动监听某些事件,并执行对应的回调函数,面试的时候问的就是自己如何实现了….

官方文档还给出了生命周期流程图,下面只给出使用vue2开发的页面声明周期流程图,与vue3对应的流程图区别只在于部分生命周期函数的名称不同(beforeDestory->beforeUnmount,Destoryed->Unmounted)

onShow和onHide

注意页面显示,是一个会重复触发的事件。a页面刚进入时,会触发a页面的onShow。

当a跳转到b页面时,a会触发onHide,而b会触发onShow。但当b被关闭时,b会触发onUnload,此时a再次显示出现,会再次触发onShow。在tabbar页面(指pages.json里配置的tabbar),不同tab页面互相切换时,会触发各自的onShow和onHide,还是比较好理解的。

onLoad

onLoad比较适合的操作是:接受上页的参数,联网取数据,更新data。其参数为上个页面传递的数据,参数类型为 Object

onReachBottom

可在pages.json里定义具体页面底部的触发距离,比如设为50(不需要单位),那么滚动页面到距离底部50px时,就会触发onReachBottom事件。

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

uni-app组成和跨端原理

组成

uni-app代码编写,基本语言包括js、vue、css。以及ts、scss等css预编译器。

在app端,还支持原生渲染的nvue,以及可以编译为kotlin和swift的uts

DCloud还提供了使用js编写服务器代码的uniCloud云引擎。所以只需掌握js,你可以开发web、Android、iOS、各家小程序以及服务器等全栈应用(我嘞个全栈啊)。

跨端原理

uni-app分编译器运行时(runtime)。uni-app能实现一套代码、多端运行,是通过这2部分配合完成的。

编译器将开发者的代码进行编译,编译的输出物(每个平台支持的特有代码)由各个终端的runtime进行解析,每个平台(Web、Android App、iOS App、各家小程序)都有各自的runtime

总结的来说,uni-app能实现跨端,基于uni-app的编译器和提供的运行时环境(runtime);

uni-app的编译器基于webpack或者vite,在编译过程中,能把基于uni-app规范编写的代码转化,打包成能在特定平台上运行的代码,并这个过程中集成相应的runtime;编译打包后的代码文件,还会被组织成在结构上符合特定平台规范的项目

编译器

  • 编译器运行在电脑开发环境。一般是内置在HBuilderX工具中,也可以使用独立的cli版。

    使用HBuilderX可视化界面创建的项目,编译器在HBuilderX的安装目录下的plugin目录,随着HBuilderX的升级会自动升级编译器。

  • 开发者按uni-app规范编写代码,由编译器将开发者的代码编译生成特定平台支持的代码

    • 在web平台,将.vue文件编译为js,css代码。与普通的vue cli项目类似
    • 在微信小程序平台,编译器将.vue文件拆分生成wxml、wxss、js等代码。
    • 在app平台,将.vue文件编译为js代码。进一步,如果涉及uts代码:
      • 在Android平台,将.uts文件编译为kotlin代码
      • 在iOS平台,将.uts文件编译为swift代码
  • 编译器分vue2版和vue3版

    • vue2版:基于webpack实现
    • vue3版:基于Vite实现,性能更快
    • 这些工具本身都是基于Node.js平台开发的,因此在你的本地开发环境中必须安装 Node.js 来运行这些构建脚本。
  • 编译器支持条件编译,即可以指定某部分代码只编译到特定的终端平台。从而将公用和个性化融合在一个工程中。

    1
    2
    3
    // #ifdef  App
    console.log("这段代码只有在App平台才会被编译进去。非App平台编译后没有这段代码")
    // #endif

运行时环境

uni-app在每个平台都准备了相应的runtime,会在编译的过程中集成到项目中。

  • uni-app给小程序端提供的runtime,主要是一个小程序版的vue runtime,页面路由、组件、api等方面基本都是转义。
  • uni-app给web端提供的runtime,相比普通的vue项目,多了一套ui库、页面路由框架、和uni对象(即常见API封装)
  • uni-app给App端提供的runtime更复杂,可以先简单理解为DCloud也有一套小程序引擎,打包app时将开发者的代码和DCloud的小程序打包成了apk或ipa。当然,事实上DCloud确实有小程序引擎产品,供原生应用实现小程序化。

uni-app提供的runtime包括3部分:基础框架、组件、API

  1. 基础框架:
    • 包括语法、数据驱动、全局文件、应用管理、页面管理、js引擎渲染和排版引擎
    • web小程序上,不需要uni-app提供js引擎排版引擎。因为浏览器有自己的webview,也就是浏览器内核,可以执行渲染和运行js代码的工作;各个小程序平台也有自己的webviewjs引擎;但安卓上,需要uni-app提供谷歌v8引擎,webview则使用系统自带的;ios上也不需要uni-app提供js引擎和webview,都使用ios系统自带的。
    • App的渲染引擎:同时提供了2套渲染引擎.vue页面文件由webview渲染,原理与小程序相同;.nvue页面文件由原生渲染,原理与react native相同。开发者可以根据需要自主选择渲染引擎。
  2. 组件
    • 在小程序端,uni-app基础组件会直接转义为小程序自己的内置组件。提供给小程序的runtime中,基础组件不占体积
    • 在web和android、iOS端,这几十个组件都在uni-app的runtime中,会占用一定体积,相当于内置了一套ui库。
  3. api
    • uni-app runtime内置了大量常见的、跨端的 API,比如联网(uni.request)、读取存储(uni.getStorage)
    • 使用uni-app的标准API,可以跨端使用。但对于不跨端的部分(就是某个平台的特色api),仍可以调用该端的专有API。由于常见的API都已经被封装内置,所以日常开发时,开发者只需关注uni标准API,当需要调用特色端能力时在条件编译里编写特色API调用代码。
    • 小程序平台:uni对象会转为小程序的自有对象,比如在微信小程序平台,编写uni.request等同于wx.request。
    • web平台:window、dom等浏览器专用API仍可以使用

逻辑层和渲染层分离

在web平台,逻辑层(js)和渲染层(html、css),都运行在统一的webview(浏览器内核)里,也就是说web平台的逻辑层和渲染层并没有分离。 但在小程序app端,逻辑层和渲染层被分离了。逻辑层独立成了单独的js引擎(jscore或者v8引擎),负责执行业务逻辑;渲染层仍然是webview,负责页面渲染。简单来说,就是由单线程转换成了双线程

要注意的是这里的app端,指的是混合开发的app,即混合了前端开发技术和app原生开发技术,而不是原生app;使用uni-app开发的app都是混合app,原生app是不涉及前端技术的,比如js的。

虽然开发者在一个 vue 页面里写 js 和 css,但其实,编译时就已经将它们拆分了。

分离的核心原因是性能。过去很多开发者吐槽 基于webview的app性能不佳,很大原因是js运算界面渲染抢资源导致的卡顿,这一也说明,webview其实是能执行js代码的,只不过为了提高性能,现在只被用来渲染。

逻辑层详解

逻辑层是运行在一个独立的 js引擎里的,它不依赖于本机的 webview,所以一方面它没有浏览器兼容问题,可以在 Android4.4 上跑 es6 代码;另一方面,它无法运行 windowdocumentnavigatorlocalstorage 等浏览器专用的 js API。

比如,jscore就是一个标准 js 引擎,可以正常运行标准 js(ECMAscript) ,比如 if、for、各种字符串、日期处理等。

  • 所谓浏览器 js 引擎,就是 jscorev8 的基础上新增了一批浏览器专用 API,比如 dom;
  • node.js 引擎,则是 v8 基础上补充一些电脑专用 API,比如本地 io;
  • 小程序端的 js 引擎,其实是在 jscore 上补充了一批手机端常用的 JS API,比如扫码;
  • 安卓端的js引擎,则是在谷歌v8引擎的基础上添加了一些手机端常用的 JS API;ios端的js引擎则是基于iOS操作系统提供的jscore

视图层详解

视图层交由webview渲染,所以什么是webview?webview是移动端原生应用中的嵌入式浏览器控件,用于在原生应用中加载网页内容,实现混合开发。

  • 在web平台并没有webview的概念,在浏览器中,渲染(浏览器引擎的布局与绘制)和js代码的执行(逻辑)共享同一线程。
  • 而小程序平台有自己的webview组件,本质也类似浏览器内核。
  • 在 iOS 上,只能使用 iOS 提供的 Webview(默认是 WKWebview)。它有一定的兼容问题,iOS 版本不同,它的表现有细微差异。
  • 安卓App 端默认使用了 Android system webview,这个安卓系统 webview 跟随手机不同而有差异。当然 App 端也支持使用腾讯 X5 引擎,此时可以在 Android 端统一视图层。

逻辑层和视图层分离的利与弊

逻辑层和视图层分离,好处是 js 运算不阻塞渲染,最简单直接的感受就是:窗体动画稳。

缺点是,逻辑层和视图层属于2个不同的线程,不同线程之间的通信是有一定延时的。

js语法

浏览器js与标准js

uni-app的js API由标准ECMAScript的js API 和 uni扩展API 这两部分组成。

标准ECMAScript的js仅是最基础的js。浏览器基于它扩展了window、document、navigator等对象。小程序也基于标准js扩展了各种wx.xx、my.xx、swan.xx的API。node也扩展了fs等模块。

所以说浏览器js不等于标准js。

ES6 支持

uni-app 在支持绝大部分 ES6 API 的同时,也支持了 ES7 的 await/async(爽)

具体支持情况参考官方文档。

App端

在App端JS脚本运行在独立的JS引擎(jscore)中,vue页面使用系统webview渲染,nvue页面使用系统原生View渲染。

Android平台

  • JS脚本运行在独立Google V8引擎中,因此支持的语法与Android系统版本无关
  • vue页面渲染在系统Webview(android system webview)中,受Android系统版本影响,当然也可以使用x5等三方webview来拉齐实现。
  • nvue页面使用系统原生View渲染,css支持情况参考:nvue页面样式

iOS平台

  • JS脚本运行在iOS操作系统提供的JsCore 引擎,因此支持的语法与iOS系统有关
  • vue页面渲染在系统WKWebview中,受iOS系统版本影响
  • nvue页面使用系统原生View渲染,css支持情况参考:nvue页面样式

总结

  • 安卓平台的js引擎是独立于安卓的,非常稳定;

    而vue页面的渲染则基于系统webview,受Android系统版本影响,但是使用第三方webview来替代安卓系统webview,从而消除安卓系统不同带来的渲染差异。

  • ios平台的js引擎是ios操作系统提供的,受iOS系统版本影响;

    而vue页面的渲染同样基于系统WKWebview,受iOS系统版本影响;

css语法

处理器支持

uni-app 支持less、sass、scss、stylus等预处理器,但是需要安装相应的插件。

尺寸单位

uni-app 支持的通用 css 单位包括 px、rpx。

  • px 即屏幕像素
  • rpx 即响应式 px,一种根据屏幕宽度自适应的动态单位。以 750 宽的屏幕为基准,750rpx 恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大,但在 App(vue2 不含 nvue) 端和 H5(vue2) 端屏幕宽度达到 960px 时,默认将按照 375px 的屏幕宽度进行计算,具体配置参考:rpx 计算配置

vue 页面还支持rem,vw,vh

nvue页面还不支持百分比单位。

样式导入

使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。

在模块化开发环境中,还可以使用import "../../common/uni.css"的方式导入css文件。

示例代码:

1
2
3
4
5
6
<style>
@import "../../common/uni.css";
.uni-card {
box-shadow: none;
}
</style>

选择器

支持的选择器包括类选择器,id选择器,标签选择器,并集选择器,伪元素选择器。

注意:

  • uni-app 中不能使用 * 选择器。

  • 微信小程序自定义组件中仅支持 class 选择器

  • page 相当于 body 节点:

    1
    2
    3
    4
    <!-- 设置页面背景颜色,使用 scoped 会导致失效 -- >
    page {
    background-color: #ccc;
    }

全局样式与局部样式

定义在 App.vue 中的样式为全局样式,作用于每一个页面。在 pages 目录下 的 vue 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 App.vue 中相同的选择器。

注意:

  • App.vue 中通过 @import 语句可以导入外联样式,一样作用于每一个页面。
  • nvue 页面暂不支持全局样式

css变量

uni-app 提供内置 CSS 变量

CSS 变量描述App小程序H5
–status-bar-height系统状态栏高度系统状态栏高度、nvue 注意见下25px0
–window-top内容区域距离顶部的距离00NavigationBar 的高度
–window-bottom内容区域距离底部的距离00TabBar 的高度

注意:

  • var(--status-bar-height) 此变量在微信小程序环境为固定 25px,在 App 里为手机实际状态栏高度。
  • 当设置 "navigationStyle":"custom" 取消原生导航栏后,由于窗体为沉浸式,占据了状态栏位置。此时可以使用一个高度为 var(--status-bar-height) 的 view 放在页面顶部,使用sticky布局,避免页面内容出现在状态栏(避免页面内容压住状态栏)。
  • 由于在 H5 端,不存在原生导航栏和 tabbar,也是前端 div 模拟。如果设置了一个固定位置的居底 view,在小程序和 App 端是在 tabbar 上方,但在 H5 端会与 tabbar 重叠。此时可使用--window-bottom,不管在哪个端,都是固定在 tabbar 上方。
  • 目前 nvue 在 App 端,还不支持 --status-bar-height变量,替代方案是在页面 onLoad 时通过 uni.getSystemInfoSync().statusBarHeight 获取状态栏高度,然后通过 style 绑定方式给占位 view 设定高度。

背景图片

uni-app 支持使用在 css 里设置背景图片,使用方式与普通 web 项目大体相同,但需要注意以下几点:

  • 支持 base64 格式图片。

  • 支持网络路径图片。

  • 小程序不支持在 css 中使用本地文件,包括本地的背景图字体文件。需以 base64 方式方可使用。

  • 在小程序中使用本地路径背景图片需注意:

    1. 为方便开发者,在背景图片小于 40kb 时,uni-app 编译到不支持本地背景图的平台时,会自动将其转化为 base64 格式;
    2. 图片大于等于 40kb,会有性能问题,不建议使用太大的背景图,如开发者必须使用,则需自己将其转换为 base64 格式使用,或将其挪到服务器上,从网络地址引用。
    3. 本地背景图片的引用路径推荐使用以~@开头的绝对路径,微信小程序不支持相对路径(真机不支持,开发工具支持)
    1
    2
    3
    .test2 {
    background-image: url('~@/static/logo.png');
    }

简单的来说就是对于小程序,在css中使用本地图片是不被支持的,如果非要使用,当图片大小小于40kb,uni-app则会帮你把它转化成base64格式,否则需要手动转化成base64格式或者网络图片,否则就会出错。

字体文件同理。

组件

自定义组件

通过uni-app的easycom, 将组件引入精简为一步。只要自定义组件安装在项目的 components 目录下,并符合 components/组件名称/组件名称.vue 目录结构。就可以不用引用、不注册,直接在页面中使用,非常方便。

说明

  • easycom自动开启的,不需要手动开启,有需求时可以在pages.jsoneasycom节点进行个性化设置,如关闭自动扫描,或自定义扫描匹配组件的策略。

    1
    2
    3
    4
    5
    6
    7
    8
    "easycom": {
    "autoscan": true,//默认开启
    //以正则方式自定义组件匹配规则。如果autoscan不能满足需求,可以使用custom自定义匹配规则
    "custom": {
    "^uni-(.*)": "@/components/uni-$1.vue", // 匹配components目录内的vue文件
    "^vue-file-(.*)": "packageName/path/to/vue-file-$1.vue" // 匹配node_modules内的vue文件
    }
    }
  • easycom方式引入的组件无需在页面内import,也不需要在components内声明,即无需引入无需注册,可在任意页面使用。
  • easycom方式引入组件不是全局引入,而是局部引入。例如在H5端只有加载相应页面才会加载使用的组件。
  • 在组件名完全一致的情况下,easycom引入的优先级低于手动引入(区分连字符形式与驼峰形式)。
  • easycom只处理vue组件,不处理小程序专用组件(如微信的wxml格式组件)

pages.json 页面路由 | uni-app官网

下载组件

uni-app有许多内置的组件,比如view,scroll-view。还有许多官方提供的扩展组件。

如果使用的是uni-ui模板的项目,则这些扩展组件都在创建项目的时候下载好了(都下载到了根目录下的uni_modules文件中),这样的好处就是不需要手动下载组件,直接使用即可;

而且这些组件并不是会无条件地,全部被打包进最终文件。具体来说,打包工具(如 Webpack 或 Vite)会根据你实际使用的组件来决定哪些内容会被包含在最终的应用程序中(tree-shaking)。

如果你没有创建uni-ui项目模板,也可以在你的工程里,通过 uni_modules 单独安装需要的某个组件。导入指定项目后直接使用即可,这些组件也无需import和注册,就可以直接使用,也是得益于eazycom机制。

常用组件

api

概述

uni-app的 js API 由标准 ECMAScript 的 js API 和 uni 扩展 API 这两部分组成。

标准 ECMAScript 的 js 仅是最基础的 js。浏览器基于它扩展了 window、document、navigator 等对象。小程序也基于标准 js 扩展了各种 wx.xx、my.xx、swan.xx 的 API。node 也扩展了 fs 等模块。

uni-app 基于 ECMAScript 扩展了 uni 对象,uni-app的几乎所有API都包含在这个对象上,并且 API 命名与小程序保持兼容。

除了 uni-app 框架内置的跨端 API(会被自动编译成特定平台对应的api),各端自己的特色 API 也可通过条件编译自由使用。各端特色 API 规范参考各端的开发文档。

API Promise 化

异步的方法,如果不传入 success、fail、complete 等 callback 参数,将以 Promise 返回数据。例如:uni.getImageInfo()

1
2
3
4
5
6
7
8
9
10
11
12
// 正常使用
const task = uni.connectSocket({
success(res){
console.log(res)
}
})
// Promise 化
uni.connectSocket().then(res => {
// 此处即为正常使用时 success 回调的 res
// uni.connectSocket() 正常使用时是会返回 task 对象的,如果想获取 task ,则不要使用 Promise 化
console.log(res)
})

原来不用自己new Promise()啊😂

网络请求

uni.request(OBJECT)

object(传入api的对象)的常用属性:

参数名类型必填默认值说明
urlString开发者服务器接口地址
dataObject/String/ArrayBuffer请求的参数
headerObject设置请求的 header,header 中不能设置 Referer
methodStringGET有效值详见下方说明
dataTypeStringjson如果设为 json,会对返回的数据进行一次 JSON.parse,非 json 不会进行 JSON.parse
responseTypeStringtext设置响应的数据类型。合法值:text、arraybuffer
withCredentialsBooleanfalse跨域请求时是否携带凭证(cookies)
deferBooleanfalse控制当前请求是否延时至首屏内容渲染后发送
successFunction收到开发者服务器成功返回的回调函数,第一个参数是个对象,属性包括:data,statusCode,header,cookies
failFunction接口调用失败的回调函数,的第一个参数是个对象,属性包括:errCode,errSubject,data,cause,errMsg
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)
  • method有效值必须大写,每个平台支持的method有效值不同

  • success 返回参数说明:

    参数类型说明
    dataObject/String/ArrayBuffer开发者服务器返回的数据
    statusCodeNumber开发者服务器返回的 HTTP 状态码
    headerObject开发者服务器返回的 HTTP Response Header
    cookiesArray<string>开发者服务器返回的 cookies,格式为字符串数组

requestTask对象

如果希望返回一个 requestTask 对象,需要至少传入 success / fail / complete 参数中的一个。例如:

1
2
3
4
5
var requestTask = uni.request({
url: 'https://www.example.com/request', //仅为示例,并非真实接口地址。
complete: ()=> {}
});
requestTask.abort();//中断请求

如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象,通过 requestTask,可中断请求任务。

对于uni.request这个api无论是否传入回调函数,都会返回一个对象,只不过返回对象的类型不同。

页面路由

uni.navigateTo(OBJECT)

  • 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面。
  • 只能跳转到非tabbar页面
  • 路由API的目标页面必须是在pages.json里注册的vue页面,如果想打开web url,参考官方文档。

OBJECT常用参数说明:

参数类型必填默认值说明
urlString需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 ‘path?key=value&key2=value2’,path为下一个页面的路径,下一个页面的onLoad函数可得到传递的参数
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

示例:

1
2
3
4
//在起始页面跳转到test.vue页面并传递参数
uni.navigateTo({
url: 'test?id=1&name=uniapp'
});
1
2
3
4
5
6
7
// 在test.vue页面接受参数
export default {
onLoad: function (option) { //option为object类型,会序列化上个页面传递的参数
console.log(option.id); //打印出上个页面传递的参数。
console.log(option.name); //打印出上个页面传递的参数。
}
}

uni.navigateBack(OBJECT)

关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。

OBJECT参数说明:

参数类型必填默认值说明
deltaNumber1返回的页面数,如果 delta 大于现有页面数,则返回到首页。
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。见下方示例代码
// 此处是A页面
uni.navigateTo({
url: 'B?id=1'
});
// 此处是B页面
uni.navigateTo({
url: 'C?id=1'
});
// 在C页面内 navigateBack,将返回A页面
uni.navigateBack({
delta: 2
});

uni.redirectTo(OBJECT)

  • 关闭当前页面,跳转到应用内的某个页面,不能跳转到 tabBar 页面。
  • 和navigateTo的主要区别是这个api会关闭当前页面,而navigateTo不会

OBJECT参数说明:

参数类型必填说明
urlString需要跳转的应用内非 tabBar 的页面的路径,路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 ‘path?key=value&key2=value2’
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

uni.reLaunch(OBJECT)

  • 关闭所有页面,打开到应用内的某个页面,包括tabbar页面。

OBJECT参数说明:

参数类型必填说明
urlString需要跳转的应用内页面路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 ‘path?key=value&key2=value2’,如果跳转的页面路径是 tabBar 页面则不能带参数
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

uni.switchTab(OBJECT)

  • 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
  • 在路径中不能携带参数。

OBJECT参数说明:

参数类型必填说明
urlString需要跳转的 tabBar 页面的路径(需同时在 pages.json 的 tabBar ,pages字段定义的页面),路径后不能带参数
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

媒体

uni.chooseImage(OBJECT)

从本地相册选择图片或使用相机拍照。

App端如需要更丰富的相机拍照API(如直接调用前置摄像头),参考plus.camera

OBJECT 参数说明:

参数名类型必填说明
countNumber最多可以选择的图片张数,默认9
sizeTypeArray<String>original 原图,compressed 压缩图,默认二者都有
extensionArray<String>根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。
sourceTypeArray<String>album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项
cropObject图像裁剪参数,设置后 sizeType 失效
successFunction成功则返回图片的本地文件路径列表tempFilePaths
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

success 返回参数说明

参数类型说明
tempFilePathsArray<String>图片的本地文件路径列表
tempFilesArray<Object>、Array<File>图片的本地文件列表,每一项是一个 File 对象

示例:

1
2
3
4
5
6
7
8
uni.chooseImage({
count: 6, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function (res) {
console.log(JSON.stringify(res.tempFilePaths));
}
});

File 对象结构如下

参数类型说明
pathString本地文件路径
sizeNumber本地文件大小,单位:B
nameString包含扩展名的文件名称,仅H5支持
typeString文件类型,仅H5支持

uni.previewImage

预览图片。

OBJECT 参数说明:

参数名类型必填说明
currentString/Number详见下方说明详见下方说明
showmenuBoolean是否显示长按菜单,默认值为 true
urlsArray<String>需要预览的图片链接列表
indicatorString图片指示器样。可取值:”default” - 底部圆点指示器; “number” - 顶部数字指示器; “none” - 不显示指示器。
loopBoolean是否可循环预览,默认值为 false
longPressActionsObject长按图片显示操作菜单,如不填默认为保存相册
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

关于current详细介绍参考官方文档。

uni.closePreviewImage(OBJECT)

OBJECT 参数说明:

参数名类型必填说明
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

uni.getImageInfo(OBJECT)

获取图片信息。

小程序下获取网络图片信息需先配置download域名白名单才能生效。

OBJECT 参数说明:

参数名类型必填说明
srcString图片的路径,可以是相对路径,临时文件路径,存储文件路径,网络图片路径
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

success 返回参数说明

参数名类型说明
widthNumber图片宽度,单位px
heightNumber图片高度,单位px
pathString返回图片的本地路径
typeString返回图片的格式

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
uni.chooseImage({
count: 1,
sourceType: ['album'],
success: function (res) {
uni.getImageInfo({
src: res.tempFilePaths[0],//传入第一个图片临时路径
success: function (image) {
console.log(image.width);
console.log(image.height);
}
});
}
});

uni.saveImageToPhotosAlbum(OBJECT)

保存图片到系统相册。

OBJECT 参数说明:

参数名类型必填说明
filePathString图片文件路径,可以是临时文件路径也可以是永久文件路径,不支持网络图片路径
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

success 返回参数说明

参数名类型说明
pathString保存到相册的图片路径,仅 App 3.0.5+ 支持
errMsgString调用结果

注意

  • 可以通过用户授权API来判断用户是否给应用授予相册的访问权限https://uniapp.dcloud.io/api/other/authorize
  • H5没有API可触发保存到相册行为,下载图片时浏览器会询问图片存放地址。
  • 微信小程序在2023年10月17日之后,使用API需要配置隐私协议

示例

1
2
3
4
5
6
7
8
9
10
11
12
uni.chooseImage({
count: 1,
sourceType: ['camera'],
success: function (res) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePaths[0],
success: function (res) {
console.log('save success',res.path);
}
});
}
});

文件

uni.saveFile(OBJECT)

OBJECT 参数说明:

参数名类型必填说明
tempFilePathString需要保存的文件的临时路径,只能是临时文件路径。
successFunction返回文件的保存路径,res = {savedFilePath: ‘文件的保存路径’}
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

success 返回参数说明:

参数说明
savedFilePath文件的保存路径

示例:

1
2
3
4
5
6
7
8
9
10
11
uni.chooseImage({
success: function (res) {
var tempFilePaths = res.tempFilePaths;
uni.saveFile({
tempFilePath: tempFilePaths[0],//选择第一个临时文件路径
success: function (res) {
var savedFilePath = res.savedFilePath;//保存成功后返回的文件路径
}
});
}
});

界面

uni.showToast(OBJECT)

显示消息提示框。

OBJECT参数说明:

参数类型必填说明
titleString提示的内容,长度与 icon 取值有关。
iconString图标,有效值详见下方说明,默认:success。
imageString自定义图标的本地路径(app端暂不支持gif)
maskBoolean是否显示透明蒙层,防止触摸穿透,默认:false
durationNumber提示的延迟时间,单位毫秒,默认:1500
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

uni.hideToast()

隐藏消息提示框。

uni.showLoading(OBJECT)

显示 loading 提示框, 需主动调用 uni.hideLoading 才能关闭提示框。

OBJECT参数说明:

参数类型必填说明
titleString提示的文字内容,显示在loading的下方
maskBoolean是否显示透明蒙层,防止触摸穿透,默认:false
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

uni.hideLoading()

隐藏 loading 提示框。

示例

1
2
3
4
5
6
7
uni.showLoading({
title: '加载中'
});

setTimeout(function () {
uni.hideLoading();
}, 2000);

uni.showModal(OBJECT)

显示模态弹窗,可以只有一个确定按钮,也可以同时有确定和取消按钮

OBJECT参数说明

参数类型必填说明
titleString提示的标题
contentString提示的内容
showCancelBoolean是否显示取消按钮,默认为 true
cancelTextString取消按钮的文字,默认为”取消”
cancelColorHexColor取消按钮的文字颜色,默认为”#000000”
confirmTextString确定按钮的文字,默认为”确定”
confirmColorHexColor确定按钮的文字颜色,H5平台默认为”#007aff”,微信小程序平台默认为”#576B95”,百度小程序平台默认为”#3c76ff”
editableBoolean是否显示输入框
placeholderTextString显示输入框时的提示文本
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

success返回参数说明

参数类型说明
confirmBoolean为 true 时,表示用户点击了确定按钮
cancelBoolean为 true 时,表示用户点击了取消(用于 Android 系统区分点击蒙层关闭还是点击取消按钮关闭)
contentStringeditable 为 true 时,值为用户输入的文本

示例

1
2
3
4
5
6
7
8
9
10
11
uni.showModal({
title: '提示',
content: '这是一个模态弹窗',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});