9 跨平台兼容

关于各端的管理规则需要耐心学习

每个端,有每个端的管理规则,这不是uni-app在技术层面上可以抹平的:

  • 比如H5端的浏览器有跨域限制;
  • 比如微信小程序会强制要求https链接,并且所有要联网的服务器域名都要配到微信的白名单中;
  • 比如App端,iOS对隐私控制和虚拟支付控制非常严格;
  • 比如App端,Android、国产rom各种兼容性差异,尤其是因为谷歌服务被墙,导致的push、定位等开发混乱的坑

H5正常但App异常的可能性

  • body的元素选择器请改为page,同样,div和ul和li等改为view、span和font改为text、a改为navigator、img改为image...
  • 使用了非H5端不支持的API 小程序和App的js运行在jscore下而不是浏览器里,没有浏览器专用的js对象,比如document、xmlhttp、cookie、window、location、navigator、localstorage、websql、indexdb、webgl等对象。

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

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

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

  • vue页面在App端的渲染引擎默认是系统webview(不是手机自带浏览器,是rom的webview),在较老的手机上,比如Android4.4、5.0或iOS8,一些新出的css语法是不支持的。注意这不意味着不能使用flex,Android4.4也支持flex,只是不要使用太新的css。可以找Android4.4手机或使用pc模拟器实际测试下,大多数国产Android模拟器都是4.4或5.0

小程序不存在浏览器兼容问题,它内置了几十M自己的定制webview。所以如果你的H5和小程序界面正常,而App界面异常,大多是因为css兼容性

解决这类问题:

放弃老款手机支持 不用使用太新的css语法,可以在caniuse查询 从 uni-app 2.5.3 起,Android端支持引入腾讯x5浏览器内核,可以抹平低端Android的浏览器兼容性问题

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

  • 在 uni-app 2.4.7 以前,H5端不支持微信小程序自定义组件,即 wxcomponents 下的组件,此时可能产生兼容问题。从 2.4.7 起,H5也支持微信自定义组件,不再存在这这方面兼容问题。
  • App端使用了App特有的API和功能,比如plus、Native.js、subNVue、原生插件等
  • 使用了小程序专用的功能,比如微信卡券、小程序插件、微信小程序云开发。对于云开发,建议使用可跨端的uniCloud

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

  • 代码中使用了App端特有的plus、Native.js、subNVue、原生插件等功能

区别于传统 web 开发的注意

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。

Tag注意

  • uni-app的tag同小程序的tag,和HTML的tag不一样,比如div要改成view,span要改成text、a要改成navigator。
  • 出于降低h5应用向uni-app迁移成本的考虑,写成div、span也可以运行在app和小程序上,因为uni-app编译器会把这些HTML标签编译为小程序标签。但仍然建议养成新习惯。

Css注意

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

工程目录注意

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

H5 开发注意

H5 发布到服务器注意

  • 配置发行后的路径(发行在网站根目录可不配置),比如发行网站路径是 www.xxx.com/html5,在 manifest.json 文件内编辑 h5 节点,router 下增加 base 属性为 html5

  • 点击菜单 发行-> H5
  • 在当下项目下的 unpackage/dist/build/h5 目录找到出的资源,部署服务器(或者使用本地服务器预览),如需部署到相对路径(支持本地file协议打开)参考:https://ask.dcloud.net.cn/article/37432

引用第三方 js 的方式:

  • 通过 npm 引入(通过条件编译,只有是 h5 平台才 import 相应的库)
  • 在 manifest.json 文件编辑 h5 节点的 template 属性,填写 html 模版路径,在 html 模版里面可以使用 script 的方式引入三方的 js,如下示例是加了百度统计的 html 模板部分代码
    <!-- ... -->
    <body>
                <noscript>
                    <strong>Please enable JavaScript to continue.</strong>
                </noscript>
                <div id="app"></div>
                <!-- built files will be auto injected -->
                <script>
                    var _hmt = _hmt || [];
                    (function() {
                        var hm = document.createElement("script");
                        hm.src = "https://hm.baidu.com/hm.js?xxxxxx";
                        var s = document.getElementsByTagName("script")[0];
                        s.parentNode.insertBefore(hm, s);
                    })();
                </script>
    </body>
    <!-- ... -->
  • H5 版 uni-app 全支持 vue 语法,所以可能造成部分写法在 H5 端生效,在小程序或 App 端不生效
  • H5 校验了更严格的 vue 语法,有些写法不规范会报警,比如: data 后面写对象会报警,必须写 function;不能修改 props 的值;组件最外层 template 节点下不允许包含多个节点等
  • 编译为 H5 版后生成的是单页应用(SPA)
  • 如果遇到跨域造成js无法联网,注意网络请求(request、uploadFile、downloadFile等)在浏览器存在跨域限制,解决方案有详见:https://ask.dcloud.net.cn/article/35267
  • 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 高度,部分浏览器还包含浏览器操作栏高度,使用时请注意
  • 正常支持 rpx,px 是真实物理像素。暂不支持通过设 manifest.json 的 "transformPx" : true,把 px 当动态单位使用
  • 使用罗盘、地理位置、加速计等相关接口需要使用 https 协议,本地预览(localhost)可以使用 http 协议
  • 组件内(页面除外)不支持 onLoad、onShow 等页面生命周期
  • 为避免和内置组件冲突,自定义组件请加上前缀(但不能是 u 和 uni)。比如可使用的自定义组件名称:my-view、m-input、we-icon,例如不可使用的自定义组件名称:u-view、uni-input,如果已有项目使用了可能造成冲突的名称,请修改名称,另外微信小程序下自定义组件名称不能以 wx 开头

小程序开发注意

vendor.js 过大的处理方式

小程序工具提示vendor.js过大,已经跳过es6向es5转换。这个转换问题本身不用理会,因为vendor.js已经是es5的了。

关于体积控制,参考如下

  • HBuilderX创建的项目勾选运行-->运行到小程序模拟器-->运行时是否压缩代码
  • cli创建的项目可以在package.json中添加参数--minimize,示例:"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize"
  • 使用分包优化

建议关注微信小程序当前bug列表 (opens new window),对已知Bug,想办法避让。

Last Updated:
Contributors: leeguooooo