一、相关概念介绍
1.uniapp介绍
- uniapp:一套代码、多端运行。核心:编译器 + 运行时
- 编译器:将uni-app统一代码编译生成每个平台支持的特有代码(生成代码)
- 运行时:让代码在不同平台上能正常运行的“执行环境”(执行代码)
2.基座相关概念
- 基座:uni-app中让代码跨平台运行的原生容器(原生层)
- 标准基座:官方预置的基础运行环境(是DCloud为方便开发者低门槛调试而提供的,此基座App使用的是DCloud的包名、证书和三方SDK配置)
- 自定义基座:开发者集成原生插件后重新编译的扩展环境(需要走一遍iOS或Android的打包流程)
- 自定义基座可以所有配置生效
- 1.App名称、图标、封面splash、包名、证书
- 2.App模块配置、三方sdk配置(如微信、推送、地图、语音识别等三方sdk配置)
- 3.App权限配置
- 4.uni原生插件
- 5.其他manifest.json文档提到的需打包生效的配置
3.版本说明
框架版本:
- 作用:决定开发者能使用的 API、组件和编译能力
- 定义:uni-app开发工具(如HBuilderX)和框架本身的版本(如 HBuilderX 3.6.18)
- 示例:
- 框架版本升级后,可能新增 uni.getBatteryInfo 接口
- 新版本可能支持微信小程序的新特性或修复旧 Bug
编译器版本和运行时版本
- 概念:
- 编译器版本(uniCompileVersion):HBuilderX的版本号。随HBuilderX工具升级但CLI项目需手动执行npm update
- 运行时版本(uniRuntimeVersion):用户设备上App的运行环境版本,需要用户主动更新App
- 取值:正常情况编译器版本和运行时版本是一样的值,即uni-app的版本。
- 编译器版本查看:
- HBuilderX方式:和HBuilderx的版本有关 (编译器在HBuilderX的安装目录下的plugin目录)
- cli方式:package.json -> @dcloudio/vue-cli-plugin-uni(编译器安装在项目下)
- 概念:
云打包机版本
- 定义:DCloud 云端服务器的引擎版本,决定生成安装包时的原生环境
应用版本:
- 作用:应用商店发布和用户升级的依据
- 定义:在manifest.json中配置的版本信息
- 版本名称:1.0.0
- 版本号:100
- 示例:每次发布新安装包(APK/IPA)需更新这两个值
资源包版本(wgt):
- 作用:支持热更新,用户无需重新安装 App 即可更新业务逻辑
- 定义:通过 HBuilderX 生成的 .wgt 文件,仅包含前端代码和静态资源
- 示例:修复 UI Bug 时生成 1.2.1.wgt,用户无感更新
4.打包方式
- 云打包
- 安心打包:不上传代码和证书
- 传统云打包:上传代码和证书(没有mac电脑但需要打iOS包的开发者)
- 本地离线打包
- 暂无
二、项目创建
1.创建方式(推荐第一种)
- 1.通过HBuilderX可视化界面:对新手友好,集成度高,可以快速上手
- 在点击工具栏里的文件 -> 新建 -> 项目(快捷键Ctrl+N)
- 2.通过vue-cli命令行:适合有经验的开发者,提供高度的定制化和灵活性
npm install -g @vue/cli vue create -p dcloudio/uni-preset-vue uniapp-empty-cli (可选择模板) npm run serve <!-- 也可通过hbuildx可视化启动 -->
2.二者区别
HBuilderX可视化界面:
- 1.工程代码在项目目录下,编译器在HBuilderX目录下,编译结果在unpackage目录下。随HBuilderX升级
- 2.HBuilderX创建的项目,一样可以使用npm(为多端兼容考虑,建议优先从uni-app插件市场获取插件。直接从npm下载库很容易只兼容H5端)
npm init -y npm install packageName --save <!-- 使用 --> import package from 'packageName' const package = require('packageName')- 优点:提升易用性,降低门槛/npm、github网络经常出问题/每个uni-app项目下都有一套编译器太麻烦/less、scss、ts等编译器的自动安装/可视化更高效
cli创建项目:
- 1.工程代码在src目录下,编译器在项目下,编译结果在dist目录下。不会跟随HBuilderX升级。需通过:npx @dcloudio/uvm@latest更新
- 2.可将src目录直接拖入到HBuilderX中运行(此时走的是HBuilderX的编译器)
- 3.想用其他ide开发uni-app,只能使用cli模式
HBuilderX创建文件目录
┌─uniCloud 云空间目录
│─components 符合vue组件规范的uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源都应存放于此目录
├─uni_modules uni-app的包管理方案:库、组件、页面、uniCloud云函数、公共模块等都可以封装成一个uni_modules
├─platforms 存放各平台专用页面的目录(暂未涉及)
├─nativeplugins App原生语言插件(暂未涉及)
├─nativeResources App端原生资源目录(暂未涉及)
│ ├─android Android原生资源目录
| └─ios iOS原生资源目录
├─hybrid App端存放本地html文件的目录(暂未涉及)
├─wxcomponents 存放微信小程序、QQ小程序组件的目录,详见
├─mycomponents 存放支付宝小程序组件的目录,详见
├─unpackage 非工程代码,一般存放运行或发行的编译结果
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见
├─uni.promisify.adaptor.js 将一些异步回调方法转换为Promise风格
└─uni.scss 内置的常用样式变量
<!-- uni.promisify的使用 -->
const getLocation = uni.promisify(uni.getLocation);
async function getUserLocation() {
try {
const location = await getLocation();
console.log('Location:', location);
} catch (error) {
console.error('Failed to get location:', error);
}
}
三、项目运行与发布
1.运行
- 1.浏览器运行:运行 -> 运行到浏览器 -> 选择浏览器
- 2.运行App到手机或模拟器:运行 -> 运行App到手机或模拟器(开启USB调试,手机上允许电脑设备调试手机)
- 3.微信开发工具:运行 -> 运行到小程序模拟器 -> 微信开发者工具
2.发布
- 1.打包为原生App:
- 发行:选择原生app-云端打包
- 注意:
- App打包时,注意如果涉及三方sdk,需进行申请并在manifest.json里配置,否则相关功能无法使用
- iOS App打包需要向Apple申请证书
- 没有mac电脑但需要打iOS包的开发者需要使用传统打包
- 2.发布为微信小程序
- 发行:”发行” => “小程序-微信”,输入小程序名称和appid点击发行即可
3.App上线步骤
注意:发版时间和更新内容
华为:
1.应用信息修改新版本特性
2.版本信息->升级->软件包管理添加打包文件,上架时间修改
vivo: 版本升级-> 上传apk,更新说明,发布时间
oppo: 版本升级-> 软件安装包,版本说明,发布时间
小米:更新版本->上传apk,定时上线,更新日志
苹果:(需要其他地方上传包 )(ios: AM是上午,PM是下午)
1.ios App+ 添加版本号
2.此版本的新增内容
3.添加构建版本
4.版本发布,时间选择
5.存储
6.添加已供审核
7.提交至app审核
四、web-view的使用
1.相关概念介绍
- web-view:承载网页的容器,会自动铺满整个页面
- uni.webView通信 uni.webview.1.5.4.js:用于H5页面与UniApp原生应用通信
- 检测当前运行环境:uni.getEnv
- H5向App发送消息:uni.postMessage,App通过@message事件接收
- 路由方法:uni.navigateBack,uni.navigateTo,uni.reLaunch,uni.redirectTo,uni.switchTab,
2.app内嵌h5传参方式
(1)URL参数传参 (app -> h5)
- 优点:实现简单,适合初始化传递少量数据。
- 缺点:数据暴露安全性差、长度受限
- 示例:
<!-- App端 --> <web-view :src="`https://h5.com?token=${token}&theme=dark`"></web-view> <!-- h5端获取 --> onMounted(() => { console.log(Object.fromEntries(new URLSearchParams(location.search).entries())) })(2)evalJS(App主动调用H5方法)
- 优点:实时性强,App可主动控制H5
- 缺点:需拼接JS字符串,无法直接获取H5返回值。iOS WebView 可能存在同步延迟
- 作用:
- 数据传递(webView.evalJS(
window.token = '${encryptedToken}';);) 注意:有时候获取数据不实时 - 触发H5函数(webView.evalJS(‘window.updateCartCount(5);’);)
- 动态修改DOM(直接操作H5页面的DOM元素)
- 数据传递(webView.evalJS(
<!-- app:传递数据 --> <!-- 下方代码获取的token不实时 --> onReady() { // #ifdef APP-PLUS let currentWebview = this.$scope.$getAppWebview() //获取当前页面的webview对象 let wv = currentWebview.children()[0] const token = uni.getStorageSync('token'); // token加密 const jsCode = ` localStorage.setItem('app_token', '${token}'); window.appTokenReady = true; `; wv.evalJS(jsCode) // #endif }, <!-- h5接受数据 --> const token = localStorage.getItem('app_token');(3)postMessage + @message(app <-> h5)
- 优点:支持双向实时通信,可传递复杂数据结构(JSON)
- 缺点:需统一消息协议(如 action 字段),H5需引入 uni.webview.js
- 应用场景:
- 用户在H5商品页点击购买按钮 → H5 通知 App 拉起支付 → App 返回支付结果(H5 → App → H5)
- H5 页面点击上传身份证 → App 调用摄像头拍照 → 返回照片路径(H5 → App → H5 )
- App 登录态过期 → 主动通知 H5 清除本地 Token(App → H5)
- App 根据 H5 页面滚动状态,动态隐藏/显示导航栏(H5 → App)
<!-- 修改token --> // app端 <web-view :src="pageData.src" @message="handleH5Message" :fullscreen="false"></web-view> <!-- 传递token到h5(app->h5) --> mounted() { let wv = this.$scope.$getAppWebview().children()[0]; const token = uni.getStorageSync('token'); const jsCode = `window.handleSetToken('${token}')` wv.evalJS(jsCode) }, <!-- h5端触发postMessage(h5->app) --> handleH5Message(e) { let wv = this.$scope.$getAppWebview().children()[0]; const { action, token } = e.detail.data[0]; if (action === 'refreshToken') { uni.setStorageSync('token', token) wv.evalJS(`window.handleSetToken('${token}')`) } } // h5端 <!-- h5端接受token --> const showToken = ref(); window.handleSetToken = (token) => { token ? localStorage.setItem('app_token', token) : localStorage.removeItem('app_token'); showToken.value = localStorage.getItem('app_token') } <!-- h5端触发修改 --> const refreshToken = () => { uni.postMessage({ data: { action: 'refreshToken', token: 888 } }); }总结
- App → H5:用evalJS(App 环境)或 URL参数传参
- H5 → App:用 uni.postMessage + @message 事件(需引入 SDK)
- 对 H5 环境使用 window.postMessage
- 混合开发中Token传递
- URL 参数加密
- evalJS 注入
- 加密URL参数 + evalJS回调(推荐)
- plus.storage共享(不推荐)
- 使用条件:只适合app:仅当H5页面被嵌入在App的WebView中,且必须等待plusready事件触发后
五、分包
1.app分包
2.小程序分包
六、App文件缓存方案(以图片为例)
1.uni-app原生Api(uni.downloadFile + uni.saveFile + storage)
- 优点:跨平台兼容(iOS/Android/H5/小程序),无需处理平台差异
- 缺点:功能较基础、目录控制能力弱
- 步骤:
- 1.uni.downloadFile:下载文件生成临时路径:_doc/temp/1.jpg
- 同一文件下载临时路径也不一致
- 应用重启后可能被自动清理-仅当前应用可用
- 2.uni.saveFile:保存文件生成沙盒路径:_doc/cached_images/1.jpg
- 永久存储-仅当前应用可用
- 3.plus.io.convertLocalFileSystemURL
- 1.uni.downloadFile:下载文件生成临时路径:_doc/temp/1.jpg
2.html5+ Api
- 优点:功能强大(支持目录操作、文件读写等),性能更高
- 缺点:仅限 App 平台,需处理平台差异
相关概念介绍
路径类型对比
沙盒路径:文件在设备中的真实物理路径
- 获取方式:plus.io.convertLocalFileSystemURL(‘_doc/‘),uni.saveFile
- 示例:/storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/doc/
- 应用场景:
- 特点:
- 应用只能访问自己的沙盒
- 卸载应用时自动清除
- 无需权限即可读写
虚拟路径:映射到沙盒的路径(沙盒路径的别名)
- 获取方式:
- 拍照:plus.camera.getCamera().captureImage
- 文件下载:plus.downloader.createDownload
- 示例:_doc/1.jpg
- 应用场景:操作文件时使用虚拟路径:ui显示,本地存储,读文件
- 获取方式:
本地URL:把虚拟路径转换成绝对路径,是沙盒路径的file://URL表示
- 获取方式:通过路径转换获得:plus.io.convertLocalFileSystemURL(path)
- 示例:/storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/doc/1.jpg
- 应用场景:原生交互使用本地URL
- 特点:
- 唯一用于WebView显示本地文件的格式
- 不可用于文件操作
- 设备重启后仍有效
临时路径:系统自动生成的短期可用路径(应用重启后自动删除)
- 获取方式:
- uni.chooseImage
- 示例:_doc/temp/
- 获取方式:
总结:
- 文件操作:始终使用虚拟路径。如:ui显示,本地存储
- 文件显示:转换为本地URL。如:上传
- 原生交互:使用沙盒路径
- 5+ Runtime内置API:分享文件
// 使用5+内置分享功能 function shareWithSystem(virtualPath) { // 需移除 file:// 前缀:兼容性考虑 const localURL = plus.io.convertLocalFileSystemURL(virtualPath) .replace(/^file:\/\//, ''); plus.share.sendWithSystem({ type: 'file', filepath: localURL }, function() { console.log('分享成功'); }, function(e) { console.error('分享失败:', e.message); });- Native.js(直接调用原生API)
- 自定义原生插件