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

条件编译
条件编译指的是:开发时,可以为不同平台编写不同的代码,分别用#ifdef和#endif,但在编译后,只保留对应平台的代码,其他平台的代码被忽略,从在实现多端兼容的同时减少打包后的代码体积
页面跳转和层级
在uni-app中,页面跳转就那五个api:
uni.navigateTo:不关闭当前页面跳转到非tabbar页面
uni.redirectTo:关闭当前页面跳转到非tabbar页面
uni.reLaunch:关闭所有页面跳转到任意页面
uni.switchTab:关闭所有非tabbar页面,跳转到tabbar页面
uni.navigateBack:关闭当前页面,回退到历史记录栈中的一个页面
层级 = 页面在栈中的深度,比如
- 首页:层级 0
- 商品页:层级 1
- 详情页:层级 2
- 评论页:层级 3
navigateBack({ delta: 2 }) 表示回退 2 层,即回到“商品页”
uni.navigateBack通常配合getCurrentPages()使用
1 | const arr = getCurrentPages() |
用uni-app开发和使用vue开发web有什么区别
标签不同
| 功能 | uni-app 标签 | Vue Web 标签 | 说明 |
|---|---|---|---|
| 块级容器 | <view> | <div> | view 是 div 的跨端替代 |
| 行内文本 | <text> | <span> | text 支持长按选中,是唯一可选中文本的标签 |
| 图片 | <image> | <img> | image 支持懒加载、缩放模式等小程序特性 |
| 按钮 | <button> | <button> 或 <div> | 两者都有 button,但属性不同 |
| 列表 | <scroll-view> 或 <list>(nvue) | <div> + CSS 滚动 | scroll-view 支持滚动事件、下拉刷新 |
| 输入框 | <input> / <textarea> | <input> / <textarea> | 属性和事件有差异 |
| 导航栏 | <navigator> | <router-link> 或 <a> | navigator 控制页面跳转 |
| 条件渲染 | <block v-if> | <template v-if> | block 不渲染为节点,仅逻辑分组 |
| 视频 | <video> | <video> | 属性和事件不同,uni-app 更简化 |
因此模板中的标签和样式中的选择器都要修改
请求的方式不同
在基于vue的web开发中,通过axios发送请求,在uni-app中,有自己的请求api,比如uni.request。
package.json文件
在hbuilder上,uni-app项目没有package.json也可以运行,因为uni-app项目使用的是自己的本地依赖。
组件库
内部有许多组件库,不能使用 Element Plus这样的组件库,因为Element Plus 是为 Vue 3 + Web(浏览器) 设计的组件库,而 uni-app 是一个多端框架,存在根本性不兼容。
pinia
在uni-app中使用vue的状态管理库比如pinia无需手动下载,直接使用即可。
vue-router
不推荐使用vue-router来进行路由跳转,而是使用自带的路由跳转api,路由传参几乎只能借助查询参数,接收路由参数也不能使用useRoute,而是在onLoad钩子中接收。
路由中的hash值无法使用
dom操作
dom操作只能在浏览器上生效,所以uni-app项目不能书写任何dom操作
事件
鼠标事件和键盘事件不能使用(除非只打包为web端)
其他
IntersectionObserver只能在支持浏览器的环境中使用- 在web开发中和uni-app跨端开发中,storage api不同,web开发中的storage api 只能在浏览器上生效。
- 不能使用布局属性比如
clientWidth。 - window和document对象也不能使用
- 阿里图标在app上不生效,因为App 端(iOS/Android)默认禁止加载外部网络资源(安全策略);小程序端不支持动态加载外部 CSS。解决方式是将阿里图标下载到本地然后再引入 (在App.vue中引入iconfont.css)
将uni-app项目编译到微信小程序,有什么注意事项
- 在
uni-app中不能使用*选择器。只能通过元素选择器来替代 - 微信小程序不支持a标签和i标签选择器,i标签会被编译成块级元素,如果i标签写在text标签中,则无法看见字体图标
- 小程序的tabbar不支持midButton
- 在微信小程序的普通组件中,只能通过
getCurrentPages来获取当前页面的查询参数,不能使用onLoad - 在微信小程序中组件标签不区分大小写,Video会被识别为video
- 微信小程序不支持ul和li标签,更不支持这2个标签的选择器
- 在小程序中checkbox-group中不能嵌套组件,即使组件中包含checkbox
- 字体图标:uni-app 在编译时,会对 static 目录下的某些资源进行处理,小于 8KB 的 .ttf, .woff 等字体文件自动转为 base64 内联,这个机制是为了减少 HTTP 请求(H5 端优化),最主要的是,小程序不支持在 css 中使用本地文件,包括本地的背景图和字体文件,需以 base64 方式方可使用。
- onPageScroll这个钩子在微信小程序中的非页面组件,无法生效
App打包需要注意些什么
静态资源文件名不能包含中文
打包前可以自定义应用图标和开屏图片,不能是webp格式的
云打包简单快捷,只需排队。本地打包虽然速度快,但是只能生成打包所需资源,最终还要使用Android Studio 进行最终的打包,需要原生开发知识,较为复杂。
如果app中包含video组件,打包前需要勾选VideoPlayer模块
在App端可以给video组件添加
vslide-gesture-in-fullscreen="true"来开启亮度和音量调节的手势。在app端中,由于视频文件上传不能分片,所以请求体的体积有时候会很大,所以需要修改nginx的配置,以支持更大的请求体:
1
2
3
4
5
6
7server {
listen 80;
server_name www.sanye.space;
# ✅ 允许最大 500MB 的请求体
client_max_body_size 500M;
}在app端中,当上传文件的时候,发现上传的速率很慢,后来才发现因为上传使用的是4G流量,使用WIFI上传就没问题了,因为:移动网络的“上传”能力天生就比“下载”弱很多
网络类型 典型下载速度 典型上传速度 上传/下载比 📶 Wi-Fi(家用宽带) 100~1000 Mbps 20~100 Mbps 较均衡 📱 4G LTE 20~100 Mbps 5~15 Mbps 上传只有下载的 1/5~1/10 📱 5G 100~1000 Mbps 10~50 Mbps 上传仍远低于下载 自定义开屏动画有图片跳动问题,目前这个问题官方还未解决,可以观察到B站软件自己也是有这个问题的,但是是用2张不同的图片来解决突兀的跳动效果的。
在uni-app中某个元素被长按,通常会被选中且有激活样式,比如navigator标签,此时我们就可以通过添加
hover-class="none"属性来解决这个问题编译到app端,输入框不会被移动键盘压住,而是会被挤压上去
在非H5端,无法通过直接修改scrollTop属性来将滚动条滚动到底部,而是可以通过使用scroll-view组件并动态修改scrollTop属性来实现:
1
<scroll-view class="content" scroll-y :scroll-top="scrollTop">
1
2
3nextTick(() => {
scrollTop.value = 99999
})在非H5端无法通过keydown事件来实现按下enter键发送消息或者评论,在uni-app中可以使用
@confirm事件,用于监听“软键盘上的确认/回车键”。@confirm在 App、H5、小程序全平台都支持!
用uni-app做图片下载和图片上传的时候,如何做到多端兼容
图片下载
H5端
使用a标签加download属性,如果是跨域资源,此时需要后端设置 Content-Disposition: attachment。
app端
先调用uni.downloadFile下载文件,在成功的回调success中拿到文件临时路径res.tempFilePath,如果下载的是图片,再调用uni.saveImageToPhotosAlbum方法,将临时文件下载到图库中。如果调用的是saveFile方法,即便文件下载成功也不知道去哪儿找。
1 | // 封装下载和保存逻辑 |
小程序端
下载图片时,最好先调用 uni.getSetting方法,检查授权情况,判断用户是否授权小程序访问图库,如果已授权,则直接下载并保存图片;如果未授权,则调用uni.authorize申请用户授权,授权成功后下载并保存图片,如果用户拒绝授权,提示用户"需要您授权保存图片到相册",如果用户同意授权,则调用uni.openSetting() 打开小程序设置页。
要注意的是 uni.getSetting,uni.authorize,uni.openSetting() 这三个方法都只能在小程序端使用
1 | const onSaveAvatar = () => { |
图片上传
图片上传前,需要先选择图片,通过调用uni.chooseImage 实现,这个方法在各端都支持。调用uni.chooseImage,在成功的回调函数中就能拿到选择的图片的临时路径,这个临时路径可以用来展示。
在uni-app中怎么做文件分片和分片上传
H5端
确定分片的起始字节编号,调用File对象的slice方法对文件进行分片即可。分片上传代码如下
1 | uploadTask = uni.uploadFile({ |
APP端
在uni-app中,App端不支持文件的分片,可以将整个文件视为一个分片,上传代码如下
1 | uploadTask = uni.uploadFile({ |
小程序端
调用 uni.getFileSystemManager得到fs对象,然后调用fs对象的readFile按范围读取文件,进行文件分片,最终得到的也是二进制文件,但是想要上传,必须确定每个分片的临时路径,所以还需要结合writeFile将文件分片写进内存得到临时文件路径,后续用户分片上传。
1 | const fs = uni.getFileSystemManager() |
1 | uploadTask = uni.uploadFile({ |
在uni-app中如何做图片裁剪
在uni-app中进行图片裁剪有多端通用的写法
1 | // 获取图片裁剪框在图片中的位置和大小 |
其他
微信开发者工具预览功能
如果预览微信小程序的时候遇到了网络错误的问题,需要选择开发调试,点击开启调试
什么是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路由,就需要后端服务器做对应的配置
当我们令运行时的基础路径为/api/,打包后index.html引入文件的路径就会变成如下:
1 | <script type="module" crossorigin src="/api/assets/index-yJj5sN9l.js"></script> |
在HBuilderX工具栏,点击发行,选择网站-H5,点击会弹出这个窗口:

无需在意,直接点击发行,即可生成 H5 的相关资源文件,保存于unpackage/dist/build/web 目录。
至于部署打包后的网页,其实和部署博客一样,可以借助github-pages+vercel,或者使用dcloud免费的网页托管服务。
发布为微信小程序
申请微信小程序AppID,参考:微信教程。
在HBuilderX中顶部菜单依次点击 “发行” => “小程序-微信”,输入小程序名称和appid点击发行即可

如果手动发行(未勾选自动上传微信平台),则点击发行按钮后,会在项目的目录 unpackage/dist/build/mp-weixin 生成微信小程序项目代码。打开微信小程序开发者工具,导入生成的微信小程序项目,测试项目代码运行正常后,点击上传按钮,之后按照 提交审核=> 发布小程序标准流程,逐步操作即可,详细查看:微信官方教程。
如果在发行界面勾选了自动上传微信平台,则无需再打开微信工具手动操作,将直接上传到微信服务器提交审核。
项目结构
下面只展示基础的项目结构,更详细的结构可以参考官方文档。
1 | │─components 符合vue组件规范的uni-app组件目录 |
微信小程序中的一个页面就是一个文件夹,然后里面有四个文件,分别对应html,css,js,json文件,而在uni-app中,一个vue文件就包含了前三者,然后页面json文件被page.json中的pages.style属性给替代了。
page.json
项目页面的配置文件 ,类似微信小程序中的app.json,这种命名方式貌似着重强调了pages属性。
主要组成:
globalStyles:全局定义页面的样式,会被pages选项中页面单独定义的样式覆盖
1 | "globalStyle": { |
可以看出,page.json文件中的globalStyles属性替换了微信小程序中的app.json文件中的window属性
pages:注册页面的地方;值是一个数组,数组元素是一个一个的页面对象,第一个页面对象就是首屏,在pages中注册的页面(路由组件)都会被打包进主包。
1 | { |
页面对象属性:
- path:页面组件路径
- style:定义页面的一些样式,比如配置,
"navigationStyle": "custom";配置后这个页面的导航栏直接消失了
tabbar:值是一个对象,用来配置标签栏。
要注意的是,H5 端有时会缓存旧的 pages.json 配置,导致配置了tabBar但是不显示的问题,此时就需要重新编译,重启项目。
1 | { |
subPackages:用来注册分包,属性的值是一个数组,数组的值是一个一个分包对象,有几个分包对象最终就有几个分包。
1 | { |
root: "subpkg",表示这个分包的根目录,是项目下的 subpkg 文件夹,所有该分包的文件都放在 subpkg/ 目录下,而pages中的页面路径相对的都是root。
分包中的页面不需要在pages.json的pages属性中注册,pages属性中注册的页面都会被打包进主包中。
更多内容参考: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 | .... |
uni.scss是一个特殊文件,在代码中无需 import 这个文件,即可在scss代码中使用这里的样式变量。uni-app的编译器在webpack配置中特殊处理了这个uni.scss,使得每个scss文件都被注入这个uni.scss,达到全局可用的效果。
简单来说,这就是一个只包含scss变量的文件,会被自动注入到所有scss文件中。
注意:如要使用这些常用变量,需要在 HBuilderX 里面安装 scss 插件;使用时需要在 style 节点上加上 lang="scss"。
pages.json不支持scss,原生导航栏和tabbar的样式修改只能使用js api。
1 | { |
uni-app 提供了 JS API 在运行时修改导航栏和 tabbar。
1 | // 修改导航栏标题 |
main.js
是 uni-app 的入口文件,类似微信小程序中的app.js文件,命名为main.js更符合vue的风格。
main.js主要作用是:
- 初始化
vue实例 - 定义全局组件
- 使用需要的插件如 i18n、vuex。
说白了不就是和vue的入口文件作用一样吗,只不过在语法上略有区别。
1 | //vue2 |
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 | <script> |
至于应用的生命周期有哪些,下面只列举了常见的部分。
| 函数名 | 说明 |
|---|---|
| onLaunch | 当uni-app 初始化完成时触发(全局只触发一次),参数为应用启动参数,同 uni.getLaunchOptionsSync 的返回值 |
| onShow | 当 uni-app 启动,或从后台进入前台显示,参数为应用启动参数 |
| onHide | 当 uni-app 从前台进入后台 |
| onError | 当 uni-app 报错时触发 |
| onUnhandledRejection | 对未处理的 Promise 拒绝事件监听函数(2.8.1+ app-uvue 暂不支持) |
| onPageNotFound | 页面不存在监听函数 |
| onLastPageBackPress | 最后一个页面按下Android back键,常用于自定义退出 |
| onExit | 监听应用退出 |
页面
uni-app项目中,一个页面就是一个 vue 文件。
在 uni-app js 引擎版中,后缀名是.vue文件或.nvue文件。 这些页面均全平台支持,差异在于当 uni-app 发行到App平台时,.vue文件会使用webview进行渲染,.nvue会使用原生进行渲染,详见:nvue原生渲染。
一个页面可以同时存在vue和nvue,在pages.json的路由注册中不包含页面文件名后缀,同一个页面可以对应2个文件名。重名时优先级如下:
- 在非app平台,先使用vue,忽略nvue
- 在app平台,使用nvue,忽略vue
weex
Weex 是由阿里巴巴集团开发的一个跨平台UI 开发框架,它允许开发者使用 Web 技术(如 HTML、CSS 和 JavaScript)来编写一次代码,并将其部署到多个平台,包括 iOS、Android 和 Web。
Weex 生成的是原生组件而不是基于WebView的渲染,因此它提供了接近原生应用的性能表现。它也通过将 js逻辑与原生渲染引擎分离,实现了高效的更新机制。Weex 的 js引擎是在基础 js引擎(如 JavaScriptCore 或 V8)的基础上进行了扩展,以支持特定的 API 和功能,但这些 API 并没有涵盖所有可能的设备功能或第三方服务集成需求。
为了解决这些问题,一些团队选择扩展 Weex 的功能集,或者转向其他提供更广泛 API 支持的框架,如 React Native 或 Flutter。此外,DCloud 的nVue框架通过增强对原生 API 的支持,解决了 Weex 在这方面的一些局限性,使前端工程师能够更加独立地开发完整应用程序。
nvue
nVue(Native Vue)是由 DCloud 公司开发的一个用于构建原生移动应用的框架。它允许开发者使用 Vue.js 语法来编写代码,但最终生成的是真正的原生 UI 组件,而不是 WebView 中的网页。
nvue如何实现原生渲染?
uni-app 的App 端内置了一个基于 weex 改进的原生渲染引擎,提供了原生渲染能力。
一个 App 中可以同时使用两种页面,比如首页使用 nvue,二级页使用 vue 页面,hello uni-app 示例就是如此。
应用场景
虽然 nvue 也可以多端编译,输出 H5 和小程序,但 nvue 的 css 写法受限,所以如果你不开发 App,那么不需要使用 nvue。
如果你熟悉 weex 或 react native 开发,那么开发app时, nvue 是你的更优选择,能切实提升你的开发效率,降低成本。
如果你是 web 前端,不熟悉原生排版,那么建议你仍然以使用 vue 页面为主,在 App 端某些 vue 页面表现不佳的场景下使用 nvue 作为强化补充。这些场景在官方文档中有介绍。
新建页面
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的都比较熟悉了。
页面生命周期
无论组件还是页面,都是vue文件,但区别在于,注册在pages.json -> pages中的组件才能算作页面。**uni-app 页面,由于既是组件又页面,所以除支持 Vue 组件生命周期外,还支持页面生命周期函数。**
当以组合式 API 使用时,在 Vue2 和 Vue3 中存在一定区别。如果使用的是vue3语法,这些uni-app页面独有的生命周期函数,使用前也要按需导入。
| 函数名 | 说明 |
|---|---|
| onLoad | 监听页面加载,该钩子被调用时,响应式数据、计算属性、方法、侦听器、props、slots 已设置完成,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例。 |
| onShow | 监听页面显示,页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 |
| onReady | 监听页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用,注意如果渲染速度快,会在页面进入动画完成前触发 |
| onHide | 监听页面隐藏 |
| onUnload | 监听页面卸载 |
| onResize | 监听窗口尺寸变化 |
| onPullDownRefresh | 监听用户下拉动作,一般用于下拉刷新 |
| onReachBottom | 页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。 |
| onShareAppMessage | 用户点击右上角分享 |
| onPageScroll | 监听页面滚动,参数为Object |
| onShareTimeline | 监听用户点击右上角转发到朋友圈 |
| onAddToFavorites | 监听用户点击右上角收藏 |
页面生命周期,说白了就是页面会自动监听某些事件,并执行对应的回调函数。
官方文档还给出了生命周期流程图,下面只给出使用vue2开发的页面声明周期流程图,与vue3对应的流程图区别只在于部分生命周期函数的名称不同(beforeDestory->beforeUnmount,Destoryed->Unmounted)

uni-app组成和跨端原理
组成
uni-app代码编写,基本语言包括js、vue、css。以及ts、scss等css预编译器。在app端,还支持原生渲染的nvue,以及可以编译为kotlin和swift的uts。
跨端原理
uni-app分为编译器和运行时(runtime)。uni-app能实现一套代码、多端运行,是通过这2部分配合完成的。
编译器将开发者的代码进行编译,编译的输出物(每个平台支持的特有代码)由各个终端的runtime进行解析,每个平台(Web、Android App、iOS 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代码
编译器分vue2版和vue3版
- vue2版:基于
webpack实现 - vue3版:基于
Vite实现,性能更快
这些工具本身都是基于Node.js平台开发的,因此在你的本地开发环境中必须安装 Node.js 来运行这些构建脚本。
编译器支持条件编译。在同一份代码中,根据目标平台的不同,只编译并保留对应平台的代码,其他平台的代码被忽略,减小打包体积
这解决了多端兼容问题,避免写大量 if-else 判断
1 | // #ifdef App |
运行时环境

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。
uni-app提供的runtime包括3部分:基础框架、组件、API。
基础框架:
- 在web和小程序上,不需要uni-app提供
js引擎和排版引擎。因为浏览器有浏览器内核,可以执行渲染和运行js代码的工作;各个小程序平台也有自己的webview和js引擎;但安卓上,需要uni-app提供谷歌v8引擎,webview则使用系统自带的;ios上也不需要uni-app提供js引擎和webview,都使用ios系统自带的。 - App的渲染引擎:同时提供了2套渲染引擎,
.vue页面文件由webview渲染,原理与小程序相同;.nvue页面文件由weex原生渲染。
组件
- 在小程序端,uni-app基础组件会直接转义为小程序自己的内置组件。提供给小程序的runtime中,基础组件不占体积
- 在web和android、iOS端,这几十个组件都在uni-app的runtime中,会占用一定体积,相当于内置了一套ui库。
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的。
分离的核心原因是性能。过去很多开发者吐槽基于webview的app性能不佳,很大原因是js运算和界面渲染抢资源导致的卡顿,这一也说明,webview其实是能执行js代码的,只不过为了提高性能,现在只被用来渲染。
逻辑层和渲染层分离的利与弊
逻辑层和渲染层分离,好处是 js 运算不阻塞渲染,缺点是,逻辑层和渲染层属于2个不同的线程,不同线程之间的通信是有一定延时的。
逻辑层详解
逻辑层是运行在一个独立的js引擎里的,它不依赖于本机的 webview,所以一方面它没有浏览器兼容问题,可以在 Android4.4 上跑 es6 代码;另一方面,它无法运行 window、document、navigator、localstorage 等浏览器专用的 js API。
比如,jscore就是一个标准 js 引擎,可以正常运行标准 js(ECMAscript) ,比如 if、for、各种字符串、日期处理等。

- 所谓浏览器 js 引擎,就是
jscore或v8的基础上新增了一批浏览器专用 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语法
浏览器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端JS脚本运行在独立的JS引擎(jscore)中,vue页面使用系统webview渲染,nvue页面使用系统原生View渲染。
Android平台
- JS脚本运行在独立Google V8引擎中,因此支持的语法与Android系统版本无关
- vue页面渲染在
系统Webview(android system webview)中,受Android系统版本影响,当然也可以使用x5等三方webview来拉齐实现。 - nvue页面使用系统原生View渲染
iOS平台
- JS脚本运行在iOS操作系统提供的JsCore 引擎,因此支持的语法与iOS系统有关
- vue页面渲染在系统
WKWebview中,受iOS系统版本影响 - nvue页面使用系统原生View渲染
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 | <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 | 系统状态栏高度 | 系统状态栏高度 | 25px | 0 |
--window-top | 内容区域距离顶部的距离 | 0 | 0 | NavigationBar 的高度 |
--window-bottom | 内容区域距离底部的距离 | 0 | 0 | TabBar 的高度 |
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 上方。
背景图片
uni-app 支持使用在 css 里设置背景图片,使用方式与普通 web 项目大体相同,但需要注意以下几点:
支持 base64 格式图片。
支持网络路径图片。
小程序不支持在 css 中使用本地文件,包括本地的背景图和字体文件。需以
base64方式方可使用。对于小程序,在css中使用本地图片是不被支持的,如果非要使用,当图片大小小于40kb,uni-app则会帮你把它转化成base64格式,否则需要手动转化成base64格式或者网络图片,否则就会出错。
字体文件同理。
组件
自定义组件
通过uni-app的easycom, 将组件引入精简为一步。只要自定义组件安装在项目的 components 目录下,并符合 components/组件名称/组件名称.vue 目录结构。就可以不用引用、不注册,直接在页面中使用,非常方便。
说明
easycom是自动开启的,不需要手动开启,有需求时可以在pages.json的easycom节点进行个性化设置,如关闭自动扫描,或自定义扫描匹配组件的策略。
1 | "easycom": { |
easycom方式引入的组件无需在页面内import,也不需要在components内声明,即无需引入无需注册,可在任意页面使用。
easycom方式引入组件不是全局引入,而是局部引入。例如在H5端只有加载相应页面,才会加载使用的组件。
在组件名完全一致的情况下,easycom引入的优先级低于手动引入(区分连字符形式与驼峰形式)。
easycom只处理vue组件,不处理小程序专用组件(如微信的wxml格式组件)
下载组件
uni-app有许多内置的组件,比如view,scroll-view。还有许多官方提供的扩展组件。
如果使用的是uni-ui模板的项目,则这些扩展组件都在创建项目的时候下载好了(都下载到了根目录下的uni_modules文件中),这样的好处就是不需要手动下载组件,直接使用即可;而且这些组件并不是会无条件地,全部被打包进最终文件。具体来说,打包工具(如 Webpack 或 Vite)会根据你实际使用的组件,来决定哪些内容会被包含在最终的应用程序中(tree-shaking)。
如果你没有创建uni-ui项目模板,也可以在你的工程里,通过 uni_modules 单独安装需要的某个组件。导入指定项目后直接使用即可,这些组件也无需import和注册,就可以直接使用,也是得益于eazycom机制。简单的来说,下载的第三方组件和在components目录中定义的组件一样,不许要注册和导入,就可以直接使用
image
<image> 组件具有默认的宽高:320*240,通常令其宽度为100%,完全贴合父元素,然后高度会等于内部图片的高度。
<image> 组件支持多种缩放模式,用于控制图片在其容器中的显示方式。这些缩放模式通过 mode 属性来设置:
scaleToFill:不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素。
aspectFit:保持纵横比缩放图片,保证图片的全部内容可见,且尽可能大地显示图片。图片可能会被包含在一个矩形框内,同时保持其比例不变。
aspectFill:保持纵横比缩放图片,并且只保证图片的短边能完整显示出来,而长边部分区域可能会被裁剪掉。
widthFix:宽度固定不变,高度随宽度自适应变化,以保持图片的比例。这种模式通常用于需要确保图片宽度一致的情况下。
heightFix:与 widthFix 类似,但这里高度是固定的,宽度随高度调整。
video
uni-app中video组件不同于h5中的video标签,其内置了许多功能,比如弹幕系统(弹幕系统不完善,只能设置滚动弹幕,而且在app端添加弹幕系统会导致应用闪退),滑动页面会自动调节播放进度。
由于在uni-app中只能让video进入全屏状态,且全屏状态自定义的controls无法展示,所以全屏状态只能使用默认的controls。
video组件在app端存在高度溢出问题,需要使用max-height:100%来限制,而且即便不进入全屏,也会压住所有元素(如果有位置重合的话),需要通过cover-view和cover-image来解决
navigator
用来替换web开发中的a标签。使用url属性来表示跳转的地址,但只能跳转本地页面。目标页面必须在pages.json中注册,其中的open-type属性用来指定跳转的方式,模拟那几个路由跳转api。
swiper
swiper的子元素是一个个swiper-item组件,swiper-item组件宽高自动设置为100%。注意:宽高100%是相对于其父组件swiper,不是相对于子组件,不能被子组件自动撑开。
然后在swiper-item中放入image组件,设置mode=widthFill再设置image宽度为100%,即可实现一个简单美观的轮播图。
uni-popup
使用频率非常高的弹窗组件,在uni-popup未被展示出来前,其内容不的结构都不会被渲染,隐藏uni-popup后,其内部的结构(包括组件)又会被销毁。
常用api
概述

uni-app的 js API ,由标准JS 和 uni 扩展 API 这两部分组成。
标准 ECMAScript 的 js 仅是最基础的 js。浏览器基于它扩展了 window、document、navigator 等对象。小程序也基于标准 js 扩展了各种 wx.xx、my.xx、swan.xx 的 API。node 也扩展了 fs 等模块。
uni-app 基于标准js扩展了 uni 对象,uni-app的几乎所有API都包含在这个对象上,并且 API 命名与小程序保持兼容。
除了 uni-app 框架内置的跨端 API(会被自动编译成特定平台对应的api),各端自己的特色 API 也可通过条件编译自由使用。
API Promise 化
异步的方法,如果不传入 success、fail、complete 等 callback 参数,将以 Promise 返回数据。例如:uni.getImageInfo()
1 | // 正常使用 |
原来不用自己new Promise()啊😂
网络请求uni.request
uni.request(obj) 是 uni-app 跨端网络请求的核心 API,封装了各端(H5、小程序、App)的原生请求能力,提供统一的调用方式。-
1 | uni.request({ |
object(传入api的对象)的常用属性:
url
url (String) 必填,请求的目标地址
- 必须是 HTTPS(小程序强制要求)
- 域名必须在各平台白名单中配置(如微信小程序需在后台配置 request 域名)
- 支持相对路径(需配合
baseURL手动处理)
data
data (Object/String/ArrayBuffer),发送给服务器的参数(请求体),会自动序列化:
- Object → 自动转为
application/x-www-form-urlencoded或application/json(取决于 header) - String → 原样发送
- ArrayBuffer → 用于上传二进制数据(如图片)
header
header (Object),设置请求头,比如
1 | header: { |
限制:
- 不能设置
Referer(小程序禁止) - 小程序对 header 键名大小写不敏感
method
method (String) ,默认 GET
有效值:GET、POST、PUT、DELETE、HEAD、OPTIONS、TRACE、CONNECT
注意:
- 小程序支持所有方法
- 某些服务器可能限制方法
- method有效值必须大写,每个平台支持的method有效值不同
dataType
dataType (String) , 默认 json,自动对返回数据调用 JSON.parse()
其他值(如 ‘text’):不解析,返回原始字符串,即使服务器返回 JSON,如果 dataType 不是 ‘json’,res.data 是字符串!
responseType
responseType (String) ,默认 text,指定响应数据类型
合法值:
'text':字符串(默认)'arraybuffer':二进制数据(用于下载文件、图片处理)
1 | // 下载图片并转为 base64 |
withCredentials
withCredentials (Boolean) ,默认 false,表示跨域请求时是否携带 Cookie,类似于 fetch 的 credentials: 'include'
用于需要登录态的接口,同时服务器需设置 Access-Control-Allow-Credentials: true
defer
defer (Boolean) , 默认 false(uni-app 3.0+)表示是否延迟请求,直到首屏内容渲染完成后再发送,用于优化首屏加载性能
适合非关键接口(如埋点、推荐列表)
建议:首屏关键接口(如用户信息)不要用 defer: true
success
success (Function),请求响应成功的回调函数,参数 res 对象包含:
1 | { |
fail
fail (Function),失败回调参数err对象包含:
1 | { |
常见 errCode:
1:参数错误2:网络连接超时3:网络请求失败
complete
complete (Function),无论成功失败都会执行,适合做隐藏 loading、结束 loading 动画
1 | uni.showLoading(); |
uni.request的返回值
如果在调用uni.request时,传入 success / fail / complete 了参数中的一个,则返回的是一个普通的requestTask对象,可以用来中断请求。
1 | var requestTask = uni.request({ |
如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象,也可以用来中断请求
1 | var requestTask = uni.request({ |
路由跳转
uni.navigateTo(object)
- 只能跳转到非tabbar页面,保留当前页面
- 路由API的目标页面必须是在
pages.json里注册的vue页面,如果想打开web url,参考官方文档。
object常用参数说明:
url(String): 必填 ,表示需要跳转的,应用内非 tabBar的页面的路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如'path?key=value&key2=value2',path为下一个页面的路径,下一个页面的onLoad函数可得到传递的参数。success(Function),非必填,接口调用成功的回调函数fail(Function),非必填,接口调用失败的回调函数complete(Function),非必填,接口调用结束的回调函数(调用成功、失败都会执行)
1 | //在起始页面跳转到test.vue页面并传递参数 |
1 | // 在test.vue页面接受参数 |
uni.navigateBack(object)
返回上一页面或多级页面,关闭当前页面,uni.navigateBack 可以回退到 tabBar 页面,但前提是该 tabBar 页面必须存在于当前页面栈中。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。
object参数说明:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| delta | Number | 否 | 1 | 返回的页面数,如果 delta 大于现有页面数,则返回到首页。 |
| success | Function | 否 | 接口调用成功的回调函数 | |
| fail | Function | 否 | 接口调用失败的回调函数 | |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例:
1 | // 注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。见下方示例代码 |
uni.redirectTo(object)
跳转到应用内的某个页面,不能跳转到 tabBar 页面,关闭当前页面。和navigateTo的主要区别是这个api会关闭当前页面,而navigateTo不会
object参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| url | String | 是 | 需要跳转的应用内非 tabBar 的页面的路径,路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 ‘path?key=value&key2=value2’ |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
uni.reLaunch(object)
关闭所有页面,打开到应用内的某个页面,包括tabbar页面。
object参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| url | String | 是 | 需要跳转的应用内页面路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 ‘path?key=value&key2=value2’,如果跳转的页面路径是 tabBar 页面则不能带参数 |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
uni.switchTab(object)
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。在路径中不能携带参数。
object参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| url | String | 是 | 需要跳转的 tabBar 页面的路径(需同时在 pages.json 的 tabBar ,pages字段定义的页面),路径后不能带参数 |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
总结
uni.navigateTo:不关闭当前页面跳转到非tabbar页面
uni.redirectTo:关闭当前页面跳转到非tabbar页面
uni.reLaunch:关闭所有页面跳转到任意页面
uni.switchTab:关闭所有非tabbar页面,跳转到tabbar页面
uni.navigateBack:关闭当前页面,回退到历史记录栈中的一个页面
媒体
uni.chooseImage(object)
从本地相册选择图片或使用相机拍照。
App端如需要更丰富的相机拍照API(如直接调用前置摄像头),参考plus.camera
object参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| count | Number | 否 | 最多可以选择的图片张数,默认9 |
| sizeType | Array<String> | 否 | original 原图,compressed 压缩图,默认二者都有 |
| extension | Array<String> | 否 | 根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。 |
| sourceType | Array<String> | 否 | album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项 |
| crop | Object | 否 | 图像裁剪参数,设置后 sizeType 失效 |
| success | Function | 是 | 成功则返回图片的本地文件路径列表tempFilePaths |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| tempFilePaths | Array<String> | 图片的本地文件路径列表 |
| tempFiles | Array<Object>、Array<File> | 图片的本地文件列表,每一项是一个 File 对象 |
示例:
1 | uni.chooseImage({ |
File 对象结构如下
| 参数 | 类型 | 说明 |
|---|---|---|
| path | String | 本地文件路径 |
| size | Number | 本地文件大小,单位:B |
| name | String | 包含扩展名的文件名称,仅H5支持 |
| type | String | 文件类型,仅H5支持 |
uni.previewImage(object)
预览图片。
OBJECT 参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| current | String/Number | 详见下方说明 | 详见下方说明 |
| showmenu | Boolean | 否 | 是否显示长按菜单,默认值为 true |
| urls | Array<String> | 是 | 需要预览的图片链接列表 |
| indicator | String | 否 | 图片指示器样。可取值:”default” - 底部圆点指示器; “number” - 顶部数字指示器; “none” - 不显示指示器。 |
| loop | Boolean | 否 | 是否可循环预览,默认值为 false |
| longPressActions | Object | 否 | 长按图片显示操作菜单,如不填默认为保存相册 |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
关于current详细介绍参考官方文档。
uni.closePreviewImage(object)
object 参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
uni.getImageInfo(object)
获取图片信息。
小程序下获取网络图片信息需先配置download域名白名单才能生效。
object参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| src | String | 是 | 图片的路径,可以是相对路径,临时文件路径,存储文件路径,网络图片路径 |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| width | Number | 图片宽度,单位px |
| height | Number | 图片高度,单位px |
| path | String | 返回图片的本地路径 |
| type | String | 返回图片的格式 |
示例
1 | uni.chooseImage({ |
uni.saveImageToPhotosAlbum(object)
保存图片到系统相册。
object参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| filePath | String | 是 | 图片文件路径,可以是临时文件路径也可以是永久文件路径,不支持网络图片路径 |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| path | String | 保存到相册的图片路径,仅 App 3.0.5+ 支持 |
| errMsg | String | 调用结果 |
注意
- 可以通过用户授权API来判断用户是否给应用授予相册的访问权限https://uniapp.dcloud.io/api/other/authorize
- H5没有API可触发保存到相册行为,下载图片时浏览器会询问图片存放地址。
- 微信小程序在2023年10月17日之后,使用API需要配置隐私协议
示例
1 | uni.chooseImage({ |
文件
uni.saveFile(object)
OBJECT 参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| tempFilePath | String | 是 | 需要保存的文件的临时路径,只能是临时文件路径。 |
| success | Function | 否 | 返回文件的保存路径,res = {savedFilePath: ‘文件的保存路径’} |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明:
| 参数 | 说明 |
|---|---|
| savedFilePath | 文件的保存路径 |
示例:
1 | uni.chooseImage({ |
界面
uni.showToast(object)
显示消息提示框。
object参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | String | 是 | 提示的内容,长度与 icon 取值有关。 |
| icon | String | 否 | 图标,有效值详见下方说明,默认:success。 |
| image | String | 否 | 自定义图标的本地路径(app端暂不支持gif) |
| mask | Boolean | 否 | 是否显示透明蒙层,防止触摸穿透,默认:false |
| duration | Number | 否 | 提示的延迟时间,单位毫秒,默认:1500 |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
uni.hideToast()
隐藏消息提示框。
uni.showLoading(object)
显示 loading 提示框, 需主动调用 uni.hideLoading 才能关闭提示框。
object参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | String | 是 | 提示的文字内容,显示在loading的下方 |
| mask | Boolean | 否 | 是否显示透明蒙层,防止触摸穿透,默认:false |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
uni.hideLoading()
隐藏 loading 提示框。
示例
1 | uni.showLoading({ |
uni.showModal(object)
显示模态弹窗,可以只有一个确定按钮,也可以同时有确定和取消按钮
object参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | String | 否 | 提示的标题 |
| content | String | 否 | 提示的内容 |
| showCancel | Boolean | 否 | 是否显示取消按钮,默认为 true |
| cancelText | String | 否 | 取消按钮的文字,默认为”取消” |
| cancelColor | HexColor | 否 | 取消按钮的文字颜色,默认为”#000000” |
| confirmText | String | 否 | 确定按钮的文字,默认为”确定” |
| confirmColor | HexColor | 否 | 确定按钮的文字颜色,H5平台默认为”#007aff”,微信小程序平台默认为”#576B95”,百度小程序平台默认为”#3c76ff” |
| editable | Boolean | 否 | 是否显示输入框 |
| placeholderText | String | 否 | 显示输入框时的提示文本 |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success返回参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| confirm | Boolean | 为 true 时,表示用户点击了确定按钮 |
| cancel | Boolean | 为 true 时,表示用户点击了取消(用于 Android 系统区分点击蒙层关闭还是点击取消按钮关闭) |
| content | String | editable 为 true 时,值为用户输入的文本 |
示例
1 | uni.showModal({ |
扩展:微信小程序
微信小程序的一键登录怎么做
调用
uni.login接口需要用户已经完成小程序验证,否则无法调用,完成小程序验证要300元/年
先调用
uni.login方法,这会发送一个请求给微信服务器,得到一个临时登录凭证code(临时登录凭证,有效期 5 分钟,只能使用一次,这个登录凭证和微信用户信息是绑定的)然后调用
uni.request方法将这个临时登录凭证,发送到小程序的后端服务器,小程序后端服务器将这个临时登录凭证code,连同小程序的APPID和APPSECRET(小程序密钥,只能在后端使用,不能暴露在前端!)发送给微信服务器,换取openid, session_key,然后返回一个token给小程序,用户的后续请求都会携带这个token,返回的token中就包含openid。openid表示用户在当前小程序下的唯一标识(每个用户 + 每个小程序,唯一),计算方式为:openid = hash(用户微信号 + 小程序 AppID),同一个用户在同一个微信小程序中,无论登录多少次,得到的openid都是完全一致的
1 | async wechatLogin() { |
如果还需要用户昵称、头像等信息,则需要调用:
1 | // 获取用户信息(需用户点击按钮授权) |
注意:getUserProfile 已被限制使用,推荐使用 <button open-type="getUserInfo"> 组件方式触发。
后端代码如下
1 | // server.js |
在微信小程序上怎么做微信支付
想在微信小程序中实现支付功能,需要先满足一下条件:
- 小程序已经上线,个人小程序不支持支付
- 个人类小程序上线,不需要支付 300 元认证费,但必须完成微信实名认证(绑定身份证)完成后可以: 提交代码审核
, 发布上线, 使用基础功能但个人小程序功能受限,不支持:微信支付,获取用户手机号,广告组件,附近的小程序 - 在
pay.weixin.qq.com申请微信商户号
然后执行如下步骤:
- 前端请求后端创建订单,后端调用微信统下单 API,生成
requestPayment所需参数并返回 - 前端调用
uni.requestPayment调起支付,用户输入密码完成支付 - 支付成功后,微信服务器异步调用小程序后端的支付回调接口,后端更新订单状态,返回 SUCCESS
- 前端跳转支付成功页
1 | <template> |
后端代码如下
1 | // Node.js 示例(Express) |
在微信小程序上怎么做分享功能
拿微信小程序举例,在 js 中定义 onShareAppMessage 处理函数(和 onLoad 等生命周期函数同级),设置该页面的分享信息,用户点击分享按钮的时候会调用。这个分享按钮可能是小程序右上角原生菜单自带的分享按钮,也可能是开发者在页面中放置的分享按钮(<button open-type="share">);此事件需要 return 一个Object,用于自定义分享内容。
现在想要使用微信小程序的分享功能,必须进行微信认证,认证需要不少的费用
如何发布微信小程序
扩展:App
在app上做如何做微信登录
在app上如何做微信支付
在app上如何做分享功能
拿分享到微信举例,微信要允许这个“外部 App”调用微信分享功能,就必须:验证这个 App 是合法的、受信任的,所以你需要在微信开放平台上注册一个“移动应用”,提交你的 App 名称、包名、签名等信息,微信审核通过后,给你一个 AppID(wx1234567890abcdef)
你在 manifest.json 中填写这个 AppID,云打包时集成进去。
第一步,进入微信开放平台https://open.weixin.qq.com,注意,不是公众平台(mp.weixin.qq.com),是 开放平台。
第二步,登录并完善开发者资质,使用你的微信扫码登录,需要 企业认证(个人账号无法创建移动应用)
需要营业执照、对公账户等,个人开发者暂时无法使用微信分享(这是微信的限制)
第三步,创建“移动应用”,进入【管理中心】,点击【创建应用】→【移动应用】,填写:应用名称(如:我的视频App),应用简介,应用图标(512x512),Android 包名(如:com.yourcompany.app),Android 签名(SHA1,从你的 keystore 获取,iOS 类似,填 Bundle ID 和证书)
第四步,提交审核,审核通过后,你会获得:AppID(如:wx1234567890abcdef),AppSecret
第五步:在 HBuilderX 中配置,打开 manifest.json,在“模块权限配置”中勾选 Share(分享),点击“配置”,填入微信开放平台的:AppID,AppSecret(可选),最后进行云打包。
