uni-app 学习:跨端开发介绍

678 阅读10分钟

uni-app 介绍

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

uni-app在跨平台的过程中,不牺牲平台特色,不限制平台的能力使用。

应用开发中,90%的常规开发,比如界面组件、联网等api,uni-app封装为可跨多端的API。

而各个端的特色功能,uni-app引入条件编译。可以优雅的在一个项目里调用不同平台的特色能力。比如push,微信小程序里不支持,但可以在App里使用,还有很多原生sdk,在App时难免涉及,这些都可以正常的在uni-app框架下使用。

uni-app是多端写在一个基础项目下,差异使用条件编译来管理。

// #ifdef APP-PLUS
仅在 App 下出现
// #endif

// #ifndef H5
不会在 H5 出现
// #endif

uni-app简单来说是 vue的语法 + 小程序的api。它遵循Vue.js语法规范,组件和API遵循微信小程序命名

uni-app 积极拥抱社区现有的现代开发流程,包括但不限于:

  • 内置了webpack/vite
  • NPM 包管理系统
  • es6+ 语法(发布时会自动编译为es5)
  • 各种预处理器(less、scss、stylus、typescript)

uni-app 支持的手机版本最低到多少?

  1. Web端:uni-app没有限制,同vue2和vue3自身能支持的浏览器版本

  2. 小程序端:uni-app没有限制,同该小程序自身能支持的最低平台

  3. App端:

    • Vue2: Android4.4+、iOS9+。Android4.4已经是2013年发布的手机了。
    • Vue3: 支持的范围是:Android >=5 (使用nvue和vue有区别。某些老国产Android5的rom无法动态升级Android system webview,此时如果使用vue页面需搭配x5内核) , iOS >= 10

H5正常但App异常的可能性

1. css 异常:

  • 不支持的选择器

非H5端不支持 * 选择器;

body的元素选择器请改为page,同样,div和ul和li等改为 view,span和font改为 text,a改为 navigator,img改为 image ...

  • 组件和页面样式相互影响

非H5端默认并未启用 scoped,如需要隔离组件样式可以在 style 标签增加 scoped 属性,H5端为了隔离页面间的样式默认启用了 scoped

  • webview浏览器兼容性

vue页面在App端,默认是被系统的webview渲染的(不是手机自带浏览器,是rom的webview),在较老的手机上,比如Android4.4、5.0或iOS8,很多css是不支持的,所以不要使用太新的css,会导致界面异常。

注意这不意味着不能使用flex,Android4.4也支持flex,只是不要使用太新的css。

可以找Android4.4手机或使用pc模拟器实际测试下,大多数国产Android模拟器都是4.4或5.0。

从 uni-app 2.5.3 起,Android端支持引入腾讯x5浏览器内核,可以抹平低端Android的浏览器兼容性问题,详见x5使用指南(opens new window)

小程序不存在浏览器兼容问题,它内置了几十M自己的定制webview。所以如果你的H5和小程序界面正常,而Android低端机App界面异常,且App没有使用x5引擎,那基本就可以判定是因为css兼容性。

app端nvue页面,不存在浏览器兼容问题,它自带一个统一的原生渲染引擎,不依赖webview。

Android4.4对应的webview是chrome37。各端浏览器内核的详情查阅,参考:关于手机webview内核、默认浏览器、各家小程序的渲染层浏览器的区别和兼容性(opens new window)

  • 原生组件层级问题 H5没有原生组件概念问题,非H5端有原生组件并引发了原生组件层级高于前端组件的概念,要遮挡video、map等原生组件,请使用cover-view组件

2. 使用了非H5端不支持的API

小程序和App的js运行在jscore下而不是浏览器里,没有浏览器专用的js对象,比如document、xmlhttp、cookie、window、location、navigator、localstorage、websql、indexdb、webgl等对象。

如果你的代码没有直接使用这些,那很可能是引入的三方库使用了这些。如果是后者,去插件市场 (opens new window)搜索替代方案。要知道非H5端的js是运行在一个独立的js core或v8下,并不是运行在浏览器里。

从HBuilderX 2.6起,App端新增了renderjs,这是一种运行在视图层的js,vue页面通过renderjs可以操作浏览器对象,进而可以让基于浏览器的库直接在uni-app的App端运行,诸如echart、threejs,详见:renderjs(opens new window)

  1. 使用了非H5端不支持的vue语法,受小程序自定义组件限制的写法,详见
  2. 不要在引用组件的地方在组件属性上直接写 style="xx",要在组件内部写样式
  3. url(//alicdn.net)等路径,改为url(https://alicdn.net),因为在App端//是file协议

小程序异常的可能性

  1. 同上
  2. v-html在h5和app-vue均支持,但小程序不支持
  3. 小程序要求连接的网址都要配白名单

小程序或App正常,但H5异常的可能性

  1. 在 uni-app 2.4.7 以前,H5端不支持微信小程序自定义组件,即wxcomponets下的组件,此时可能产生兼容问题。从 2.4.7 起,H5也支持微信自定义组件,不再存在这这方面兼容问题。
  2. App端使用了App特有的API和功能,比如plus、Native.js、subNVue、原生插件等。
  3. 使用了小程序专用的功能。

区别于传统 web 开发的注意

  1. JS注意

    • 非H5端,不能使用浏览器自带对象,比如document、window、localstorage、cookie等,更不能使用jquery等依赖这些浏览器对象的框架。因为各家小程序快应用都不支持这些对象。

    • 没有这些浏览器自带对象并不影响业务开发,uni提供的api足够完成业务。

    • uni的api在编译到web平台运行时,其实也会转为浏览器的js api。

    • App端若要使用操作window、document的库,需要通过renderjs来实现。

    • uni的api是多端可用的。在条件编译区,每个平台的专有api也可以使用,比如wx.、plus.等api可以分别在微信下和app下使用。

    • 出于降低小程序向uni-app迁移成本的考虑,wx的api在app里也可以直接运行,比如写wx.request和uni.request是一样的,但仍然建议仅在微信的条件编译区使用wx的api。

  2. Tag注意

    • uni-app的tag同小程序的tag,和HTML的tag不一样,比如div要改成view,span要改成text、a要改成navigator。
    • 出于降低h5应用向uni-app迁移成本的考虑,写成div、span也可以运行在app和小程序上,因为uni-app编译器会把这些HTML标签编译为小程序标签。但仍然建议养成新习惯。(个人想法:既然uni-app编译器支持,那依然建议使用div/span/img/a,与标准一致,不必增加额外的转换负担)
  3. CSS注意

    • 虽然大部分css样式在微信小程序和app中都可以支持,但推荐使用flex布局模型,这种布局更灵活高效且支持更多平台(比如nvue、快应用只支持flex布局)
    • 单位方面,uni-app默认为rpx。这是一种可跨端的通用单位 详见
  4. 工程目录注意

    • 页面文件:放到pages目录下;推荐方案:新建一个页面目录,然后创建一个目录同名的.vue文件,如/pages/list/list.vue,接着在pages.json里完成注册。这与小程序的策略相同。
    • 自定义组件:放到component目录
    • 静态资源:如图片,固定放到static目录下。这是webpack的规则
  5. 数据绑定方式的注意

    • uni-app 基于Vue 2.0实现
  6. 每个页面支持使用原生title,首页支持使用原生底部tab,这些是要在pages.json里配置,这些并不是vue页面的一部分。当然vue里的js api也可以动态修改原生title

  7. 虽然使用vue,但在app和小程序里,不是SPA而是MPA

  8. 位置坐标系统一为国测局坐标系gcj02,这种坐标系可以被多端支持。

H5 开发注意

  • H5 发布到服务器注意:

    配置发行后的路径(发行在网站根目录可不配置)

  • 引用第三方 js 的方式:

    1. 通过 npm 引入(通过条件编译,只有是 h5 平台才 import 相应的库)
    2. 在 manifest.json 文件编辑 h5 节点的 template 属性,填写 html 模版路径,在 html 模板里面可以使用 script 的方式引入三方的 js
  • APP 和小程序的导航栏和 tabbar 均是原生控件,元素区域坐标是不包含原生导航栏和 tabbar 的;而 H5 里导航栏和 tabbar 是 div 模拟实现的,所以元素坐标会包含导航栏和tabbar的高度。为了优雅的解决多端高度定位问题,uni-app 新增了2个css变量:--window-top 和 --window-bottom,这代表了页面的内容区域距离顶部和底部的距离。举个实例,如果你想在原生tabbar 上方悬浮一个菜单,之前写 bottom:0。这样的写法编译到 h5 后,这个菜单会和 tabbar 重叠,位于屏幕底部。而改为使用 bottom:var(--window-bottom),则不管在 app 下还是在h5下,这个菜单都是悬浮在 tabbar 上浮的。这就避免了写条件编译代码。当然仍然也可以使用 H5 的条件编译处理界面的不同

  • CSS 内使用 vh 单位的时候注意 100vh 包含导航栏,使用时需要减去导航栏和 tabBar 高度,部分浏览器还包含浏览器操作栏高度,使用时请注意。

  • 正常支持 rpxpx 是真实物理像素。暂不支持通过设 manifest.json 的 "transformPx" : true,把 px 当动态单位使用。

  • 使用罗盘、地理位置、加速计等相关接口需要使用 https 协议,本地预览(localhost)可以使用 http 协议。

  • PC 端 Chrome 浏览器模拟器设备测试的时候,获取位置 API 需要连接谷歌服务器。

  • 组件内(页面除外)不支持 onLoadonShow 等页面生命周期。

  • 为避免和内置组件冲突,自定义组件请加上前缀(但不能是 u 和 uni)。比如可使用的自定义组件名称:my-viewm-inputwe-icon,例如不可使用的自定义组件名称:u-viewuni-input,如果已有项目使用了可能造成冲突的名称,请修改名称,另外微信小程序下自定义组件名称不能以 wx 开头。

小程序开发注意

各家小程序实现机制不同,可能存在的平台兼容问题

微信(可以使用virtualHost配置)/QQ/百度/字节跳动这四家小程序,自定义组件在渲染时会比App/H5端多一级节点,在写样式时需要注意