一、uni-app 创建方式
-
HBuilderX 直接创建 uni-app 项目
新建 --> 项目 --> uni-app
cli项目整个拖入 HBuilderX,编译走项目下编译器; cli项目下 src目录拖入HBuilderX中,编译走HBuilderX下plugin下编译器。
优点:
1、编译器在HBuilderX安装目录下的plugin目录下,随HBuilderX升级而自动升级。
缺点:
1、发布APP必须使用HBuilderX(H5小程序不用);
2、发布APP需下载HBuilderX(APP开发版)。 -
vue-cli 命令行创建(需要全局安装 vue-cli)
// 全局安装 vue-cli npm install -g @vue/cli // 创建 uni-app vue create -p dcloudio/uni-preset-vue my-project //运行并发布 uni-app npm run dev:%PLATFORM% //编译出各平台代码存放于根目录下的/dist/dev目录(h5不在此目录,存在于缓存) npm run build:%PLATFORM% //编译出各平台代码存放于根目录下的/dist/build目录,用于发布
选择自定义模板时,需要填写 uni-app 地址(托管云端的仓库地址)。
%PLATFORM% : h5(H5)、mp-alipay(支付宝小程序)、mp-baidu(百度小程序)、mp-weixin(微信小程序)、mp-toutiao(头条小程序)、mp-qq(QQ小程序)。
dev 和 build 的区别:
1、dev 模式有 SourceMap 可以方便的进行断点调试;
2、build 模式会将代码进行压缩,体积更小更适合发布为正式版应用;
3、进行环境判断时,dev 模式 process.env.NODE_ENV 的值为 development,build 模式 process.env.NODE_ENV 的值为 production。优点:
1、cli创建项目,HBuilderX下载10MB标准版即可(编译器已在项目下);
2、可自定义 webpack,有灵活度;
3、cli内置 d.ts可在 vscode 等支持 d.ts 开发工具正常开发且有提示。缺点:
1、若想安装 less、scss、ts 等编译器,需手动 npm 才能安装;
2、其他开发工具相比HBuilderX效率不足,且发布 APP 需要HBuilderX;
3、cli创建的项目,编译器安装在项目下。不会跟随HBuilderX升级。如需升级编译器,执行npm update。
二、实现多端兼容开发规范
- 页面文件遵循 Vue 单文件组件 (SFC) 规范
- 组件标签靠近小程序规范
- 接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni
- 数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生命周期
- 为兼容多端运行,建议使用flex布局进行开发
三、多端差异性分析
-
目录结构
┌─components uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─common 公用的资源(如css、less、scss)存放目录
├─hybrid 存放本地网页的目录
├─platforms 存放各平台专用页面的目录
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─wxcomponents 存放小程序组件的目录,详见
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json 配置应用名称、appid、logo、版本等打包信息
└─pages.json 配置页面路由、导航条、选项卡等页面类信息Tips:
1、static 目录下的 js 文件不会被编译,如果里面有 es6 的代码,不经过转换直接运行,在手机设备上会报错。
2、HbuilderX 1.9.0+ 支持在根目录创建 ext.json sitemap.json 文件。多端差异:
1、其他有效目录:app-plus(5+APP)、h5(H5)、mp-weixin(微信小程序)、mp-alipay
(支付宝小程序)、mp-baidu(百度小程序)。 -
生命周期
uni-app 支持的应用生命周期: onLaunch、onShow、onHide
应用生命周期仅可在App.vue中监听,在其它页面监听无效。
uni-app 支持的页面生命周期: 页面生命周期
多端差异:
1、使用 nvue(用于APP开发) 时支持的应用生命周期: onUniNViewMessage(对 nvue 页面发送的数据进行监听)
2、使用 nvue(用于APP开发) 时支持的页面生命周期: nvue支持的页面生命周期
-
路由(交由框架统一管理)
在pages.json里配置每个路由页面的路径及页面样式,不支持 Vue-Router。
路由跳转 及 页面栈 (与小程序相同,不赘述) -
运行环境判断
process.env.NODE_ENV = development(开发环境)/ production(生产环境)
判断平台:
-
编译期判断:打包之前判断,区分各平台专属打包。
条件编译: 以 #ifdef(仅在某平台存在) 或 #ifndef (除了某平台均存在)加 %PLATFORM% (平台名称)开头,以 #endif 结尾。
%PLATFORM% 取值:APP-PLUS(5+App)、APP-PLUS-NVUE(5+App nvue)、H5(H5)、MP-WEIXIN(微信小程序)、MP-ALIPAY(支付宝小程序)、MP-BAIDU(百度小程序)、MP-TOUTIAO(头条小程序)、MP-QQ(QQ小程序)、MP(微信小程序/支付宝小程序/百度小程序/头条小程序/QQ小程序)
Tips:
条件编译是利用注释实现的,在不同语法里注释写法不一样,js使用 // 注释、css 使用 /* 注释 */、vue/nvue 模板里使用 <! – 注释 -->;
-
运行期判断:(判断客户端环境) uni.getSystemInfoSync().platform = android(安卓)/ios(苹果)/devtools(小程序)
-
-
页面样式布局
-
尺寸单位
uni-app:upx
但 uni-app 同样支持的通用 css 单位包括 px、rpx、vh等
多端差异:
1、h5端还支持 rem(默认根字体大小为 屏幕宽度/20);
2、App端,在 pages.json 里的 titleNView 或页面里写的 plus api 中涉及的单位,只支持 px。注意此时不支持 rpx;
3、nvue中,uni-app 模式(nvue 不同编译模式介绍)可以使用 px 、rpx,表现与 vue 中一致,weex 模式目前遵循weex的单位:px: 以750宽的屏幕为基准动态计算的长度单位,与 vue 页面中的 rpx 理念相同。(一定要注意 weex 模式的 px,和 vue 里的 px 逻辑不一样。)
wx: 与设备屏幕宽度无关的长度单位,与 vue 页面中的 px 理念相同 -
样式导入
uni-app: @import + 外联样式表的相对路径
-
内联样式
style: style 接收动态的样式,在运行时会进行解析(避免在 style 里使用静态样式,降低渲染速度)。
class: 样式类名(静态样式)。
-
选择器
uni-app:.class、#id、element、element, element
多端差异:
仅微信小程序和5+App生效:::before、::after(在 view 组件前/后边插入内容)
-
全局样式与局部样式
uni-app:与微信小程序、vue 一致。
-
CSS变量
uni-app 提供内置 CSS 变量:–status-bar-height(系统状态栏高度)、–window-top(内容区域距离顶部的距离)、–window-bottom(内容区域距离底部的距离)
–status-bar-height:系统状态栏高度(5+App)、25px(小程序)、0(H5)
–window-top :0(5+App)、0(小程序)、NavigationBar 的高度(H5)
–window-bottom:0(5+App)、0(小程序)、TabBar 的高度(H5)多端差异:
1、小程序: 当设置 “navigationStyle”:“custom” 取消原生导航栏后,由于窗体为沉浸式,占据了状态栏位置。此时可以使用一个高度为 var(–status-bar-height) 的 view 放在页面顶部,避免页面内容出现在状态栏。
2、H5:不存在原生导航栏和tabbar,也是前端div模拟。如果设置了一个固定位置的居底view,在小程序和App端是在tabbar上方,但在H5端会与tabbar重叠。此时可使用–window-bottom,不管在哪个端,都是固定在tabbar上方。
-
固定值
uni-app:NavigationBar(导航栏 )、TabBar(底部选项卡 )固定。
-
Flex布局
全部使用 Flex 布局以兼容多端
-
背景图片
uni-app 支持使用在 css 里设置背景图片
1、支持 base64 格式图片。
2、支持网络路径图片。
3、使用本地路径背景图片。使用本地路径背景图片需注意:
1、图片小于 40kb,uni-app 会自动将其转化为 base64 格式;
2、图片大于等于 40kb, 需开发者自己将其转换为base64格式使用,或将其挪到服务器上,从网络地址引用。
本地背景图片的引用路径仅支持以 ~@ 开头的绝对路径(不支持相对路径)。
background-image: url('~@/static/logo.png');
-
字体图标
uni-app 支持使用字体图标
1、支持 base64 格式字体图标。
2、支持网络路径字体图标。
3、网络路径必须加协议头 https。
4、从 http://www.iconfont.cn 上拷贝的代码,默认是没加协议头的。
5、uni-app 本地路径图标字体。使用本地路径字体图标需注意:
1、字体文件小于 40kb,uni-app 会自动将其转化为 base64 格式;
2、字体文件大于等于 40kb, 需开发者自己转换,否则使用将不生效;
3、字体文件的引用路径仅支持以 ~@ 开头的绝对路径(不支持相对路径)。
-
-
< template/> 和 < block/>
uni-app:用于列表渲染和条件渲染(仅包装元素,不做渲染,只接受控制属性)
-
ES6 支持
多端不区分,只区分系统,少数不支持:
normalize(ios8、ios9)
values(ios8、android)
includes(ios8)
Proxy(ios8、ios9、android) -
NPM支持
uni-app支持使用npm安装第三方包。
// 初始化npm工程 npm init -y // 安装依赖 npm install packageName --save // 使用 import package from 'packageName' const package = require('packageName')
Tips:
1、为多端兼容考虑,建议优先从 uni-app插件市场 获取插件。直接从 npm 下载库很容易只兼容H5端。
2、非 H5 端不支持使用含有 dom、window 等操作的 vue 组件和 js 模块,安装的模块及其依赖的模块使用的 API 必须是 uni-app 已有的 API(兼容小程序 API),比如:支持高德地图微信小程序 SDK。类似jQuery 等库只能用于H5端。
3、node_modules 目录必须在项目根目录下。
4、支持安装 mpvue 组件,但npm方式不支持小程序自定义组件(如 wxml格式的vant-weapp)。
5、关于ui库的获取,详见多端UI库。 -
TypeScript 支持
在 uni-app 中使用 ts 开发, Vue.js TypeScript 支持 说明。
在 script 节点声明 lang=“ts” 后,该 vue 文件 import 进来的所有 vue 组件,均需要使用 ts 编写。
-
小程序组件支持
支持各类自定义组件
多端差异:
以下为各端支持的组件(需要了解各端小程序组件的使用方法)以及存放目录。
1、5+App:wxcomponents(微信小程序组件)
2、微信小程序:wxcomponents(微信小程序组件)
3、支付宝小程序:mycomponents(支付宝小程序组件)
4、百度小程序:swancomponents(百度小程序组件)
5、头条小程序:ttcomponents(支持头条小程序组件)使用方式: 在 pages.json 对应页面的 style -> usingComponents 引入组件
{ "pages": [ { "path": "index/index", "style": { "usingComponents": { // #ifdef APP-PLUS || MP-WEIXIN "custom": "/wxcomponents/custom/index" // #endif // #ifdef MP-BAIDU "custom": "/swancomponents/custom/index" // #endif // #ifdef MP-ALIPAY "custom": "/mycomponents/custom/index" // #endif } } } ] }
Tips:
1、HBuilderX 建立的工程 wxcomponents 文件夹在 项目根目录下。
2、vue-cli 建立的工程 wxcomponents 文件夹在 src 目录下。
3、注意数据和事件绑定的差异,使用时应按照 vue 的数据和事件绑定方式。属性绑定从 attr="{{ a }}",改为 :attr=“a”;从 title=“复选框{{ item }}” 改为 :title="‘复选框’ + item"
事件绑定从 bind:click=“toggleActionSheet1” 改为 @click=“toggleActionSheet1”
阻止事件冒泡 从 catch:tap=“xx” 改为 @tap.native.stop=“xx”
wx:if 改为 v-if
wx:for="{{ list }}" wx:key="{{ index }}" 改为`v-for="(item,index) in list"
原事件命名以短横线分隔的需要手动修改小程序组件源码为驼峰命名,比如:this. e m i t ( ′ l e f t − c l i c k ′ ) 修 改 为 t h i s . emit('left-click') 修改为 this. emit(′left−click′)修改为this.emit(‘leftClick’)(HBuilderX 1.9.0+ 不再需要修改此项)