uni-app之重点掌握

一、相关概念介绍

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元素)
        <!-- 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

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)
      • 自定义原生插件

七、App升级中心

八、App权限判断和提示

九、全局变量的实现方式

×

喜欢就点赞,疼爱就打赏