官方文档

看本篇文章需要有一点 Vue 基础

简介

什么是 uni-App

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

DCloud公司拥有500万开发者用户,几十万应用案例、10亿手机端月活用户,数千款uni-app插件、70+微信/qq群。阿里小程序工具官方内置uni-app(详见),腾讯课堂官方为uni-app录制培训课程(详见),开发者可以放心选择。

uni-app在手,做啥都不愁。即使不跨端,uni-app也是更好的小程序开发框架(详见)、更好的App跨平台框架、更方便的H5开发框架。不管领导安排什么样的项目,你都可以快速交付,不需要转换开发思维、不需要更改开发习惯。

官方文档地址:uni-App

我为什么要用 uni-App

功能框架图

首先我对 Vue 比较熟悉,其次用原生小程序的语法开发实在是不顺手,再就是一套代码就可以适配多端,不用那么重复的写。

注意事项

uni-app 使用vue的语法+小程序的标签和API。

开发规范

为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:

  • 页面文件遵循 Vue 单文件组件 (SFC) 规范
  • 组件标签靠近小程序规范,详见uni-app 组件规范
  • 接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni,详见uni-app接口规范
  • 数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生命周期
  • 为兼容多端运行,建议使用flex布局进行开发

第三条是特别要注意的!这一点很重要

目录结构

一个uni-app工程,默认包含如下目录及文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌─components            uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─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 配置页面路由、导航条、选项卡等页面类信息

特别注意:

  • static 目录下的 js 文件不会被编译,如果里面有 es6 的代码,不经过转换直接运行,在手机设备上会报错。
  • cssless/scss 等资源同样不要放在 static 目录下,建议这些公用的资源放在 common 目录下。
  • HbuilderX 1.9.0+ 支持在根目录创建 ext.json sitemap.json 文件。
有效目录 说明
app-plus App
h5 H5
mp-weixin 微信小程序
mp-alipay 支付宝小程序
mp-baidu 百度小程序

好了好了,废话够多了,如果想看其他的有关信息,请访问官方文档

开始

新建项目

官方推荐通过 HBuilderX创建项目,但是我实在是用不惯这编辑器,你要是想了解一下,一样,看官方文档

通过 VueCli 创建项目

安装 Vue:

1
npm install -g @vue/cli

创建正式版项目:

1
vue create -p dcloudio/uni-preset-vue [name]

创建 Alpha 版:

1
vue create -p dcloudio/uni-preset-vue#alpha [name]

name 为项目名称

执行命令之后会让你选择模板,选择默认即可。

选择自定义模板时,需要填写 uni-app 模板地址,这个地址其实就是托管在云端的仓库地址。以 GitHub 为例,地址格式为 userName/repositoryName,如 dcloudio/uni-template-picture 就是下载图片模板。

更多支持的下载方式,请参考这个插件的说明:download-git-repo

运行和发布

1
2
npm run dev:%PLATFORM%
npm run build:%PLATFORM%

%PLATFORM% 可取值如下:

平台
app-plus app平台生成打包资源(支持npm run build:app-plus,可用于持续集成。不支持run,运行调试仍需在HBuilderX中操作)
h5 H5
mp-alipay 支付宝小程序
mp-baidu 百度小程序
mp-weixin 微信小程序
mp-toutiao 字节跳动小程序
mp-qq qq 小程序
mp-360 360 小程序
quickapp-webview 快应用通用
quickapp-webview-union 快应用联盟
quickapp-webview-huawei 快应用华为

本文只会用到 mp-weixin 其他用法请自行查阅。

工具区别

编译器的区别

  • cli 创建的项目,编译器安装在项目下。并且不会跟随HBuilderX升级。如需升级编译器,执行 npm update,或者手动修改 package.json 中的 uni 相关依赖版本后执行 npm install。更新后可能会有新增的依赖并不会自动安装,手动安装缺少的依赖即可。
  • HBuilderX可视化界面创建的项目,编译器在HBuilderX的安装目录下的plugin目录,随着HBuilderX的升级会自动升级编译器。
  • 已经使用cli创建的项目,如果想继续在HBuilderX里使用,可以把工程拖到HBuilderX中。注意如果是把整个项目拖入HBuilderX,则编译时走的是项目下的编译器。如果是把src目录拖入到HBuilderX中,则走的是HBuilderX安装目录下plugin目录下的编译器。
  • cli版如果想安装less、scss、ts等编译器,需自己手动npm安装。在HBuilderX的插件管理界面安装无效,那个只作用于HBuilderX创建的项目。

开发工具的区别

  • cli创建的项目,内置了d.ts,同其他常规npm库一样,可在vscodewebstorm等支持d.ts的开发工具里正常开发并有语法提示。
  • 使用HBuilderX创建的项目不带d.ts,HBuilderX内置了uni-app语法提示库。如需把HBuilderX创建的项目在其他编辑器打开并且补充d.ts,可以在项目下先执行 npm init,然后npm i @types/uni-app -D,来补充d.ts。
  • 但vscode等其他开发工具,在vue或uni-app领域,开发效率比不过HBuilderX。详见:https://ask.dcloud.net.cn/article/35451
  • 发布App时,仍然需要使用HBuilderX。其他开发工具无法发布App,但可以发布H5、各种小程序。如需开发App,可以先在HBuilderX里运行起来,然后在其他编辑器里修改保存代码,代码修改后会自动同步到手机基座。
  • 如果使用cli创建项目,那下载HBuilderX时只需下载10M的标准版即可。因为编译器已经安装到项目下了。

开始学习

创建一个简单项目

执行命令:

1
vue create -p dcloudio/uni-preset-vue test

注意,项目名称不可以有大写

执行命令之后会让你选择是否使用淘宝镜像,输入 Y/y 即可

选择模板

选择默认模板即可,然后等待下载完成。

目录

这是刚创建好的项目目录结构,具体的目录结构功能请看文章开头注意事项中的目录结构

src

我们主要是在 src 目录里写代码。

目录

大概会用到的就这么多。

试运行

默认模板是可以直接运行的,命令:

1
npm run dev:mp-weixin

直接运行到微信小程序

注意,需要安装微信开发者工具。命令运行前请打开开发者工具

开始编译

静静等待,第一次编译可能比较慢。

编译成功

编译成功。

注意:uni-App 支持热加载,只需要运行一次,只要你不关闭这个运行任务,你修改项目内容之后他就会差量编译,然后直接在微信开发者工具里就可以看到修改后的效果。

打开开发者工具

添加

导入项目

选择路径的时候要注意了,导入项目的目录是 你创建项目根目录/dist/dev/mp-weixin/

!!!路径一定要选择正确,不然会影响你之后的运行和发布

然后小程序名称和 AppID 会自动导入,不用修改,等待开发者工具编译完成就是如下页面:

微信开发者工具

可以在左上角关闭编辑器,方便查看控制台报错信息。

功能

  • 1:预览样式,可以在左上角调整预览设备,查看不同设备下的预览效果
  • 2:编译模式,在只需要修改某一个页面的时候可以更改编译模式,减少性能消耗,提高预览速度
  • 3:小程序相关设置,比如信任域名、AppID等
  • 4:控制台,跟浏览器的开发者工具几乎一模一样,用来调试错误

输出信息

前两行是小程序的生命周期函数输出,不用理会,可以在 App.vue 里修改

App.vue

声明周期后面会讲到,现在不用理会。

第三行的信息是页面索引值,也不用理会,直接忽略即可,第四行的信息是你的 AppID 无效,因为我们直接是用的默认模板,它里面的 AppID 只是为了开发的时候测试用,会限制很多 API 的返回数据,所以你如果要真的开发项目,请去微信公众平台注册小程序,获取 AppID :

修改ID

关于第三行的索引值,我找来了更详细的说法:

索引值

附上官方文档地址:sitemap 配置

如果不需要这个配置,请按照下图设置:

sitemap

将属性改为 false 即可,这个方法实属不推荐,因为下次编译的时候就可能被覆盖,更稳妥的设置方法请看下文的文件讲解第一部分。

文件讲解

manifest.json

小程序能用到的

小程序能用到的

manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。

具体的各个配置项我这里就懒得啰嗦了,请参考官方文档

这里需要注意的一点是 AppID:

  • uni-app 的 appid 由 DCloud 云端分配,主要用于 DCloud 相关的云服务,请勿自行修改
  • 注意区分 uni-app 的 appid 与微信小程序、iOS 等其它平台分配的 appid,以及第三方 SDK 的 appid

上面的第一个截图就是 uni-app 的 AppID,第二个才是小程序的配置,请注意分别,如果自己有 AppID,请修改下面的,当然第一行的 name 是通用的,为小程序的名称

总结一下:这个文件如果需要修改,只修改第一行的 name 和下面的小程序相关,其他的自行查阅文档根据自己需要修改

比如前文提到的小程序 sitemap 规则,就可以在这里进行修改:

小程序设置

当然,其他小程序的相关设置也可在这里进行添加。

pages.json

pages

这里是放页面相关的配置,比如导航栏,页面路径,页面样式等

这里的样式并不是页面内容的 CSS 样式,是整个页面的样式,例如顶部栏的颜色,页面标题等

这个文件的配置至关重要,如果你写了一个新的页面,却发现无法访问的时候,记得检查这里的配置,看你是否把新的页面添加进环境里。

main.js

main.js是 uni-app 的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如 vuex。

首先引入了Vue库和App.vue,创建了一个vue实例,并且挂载vue实例。

1
2
3
4
5
6
7
8
9
10
11
12
import Vue from 'vue'
import App from './App'
import pageHead from './components/page-head.vue' //全局引用page-head组件

Vue.config.productionTip = false
Vue.component('page-head', pageHead) //全局注册page-head组件,每个页面将可以直接使用该组件
App.mpType = 'app'

const app = new Vue({
...App
})
app.$mount() //挂载Vue实例

使用Vue.use引用插件,使用Vue.prototype添加全局变量,使用Vue.component注册全局组件。

可以引用vuex,因涉及多个文件,此处没有提供示例,详见hello uni-app示例工程。

无法使用vue-router,路由须在pages.json中进行配置,后面会讲到。

nvue 暂不支持在 main.js 注册全局组件

App.vue

App.vue是 uni-app 的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素。

这个文件的作用包括:调用应用生命周期函数、配置全局样式、配置全局的存储 globalData

应用生命周期仅可在App.vue中监听,在页面监听无效。

uni.css

这个文件在本文章里是没有用的,因为需要 HBuilderX 的插件支持,所以了解了解就行了

uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量预置。

uni-app 官方扩展插件(uni ui)及 插件市场 上很多三方插件均使用了这些样式变量,如果你是插件开发者,建议你使用 scss 预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App。

uni.scss是一个特殊文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的编译器在webpack配置中特殊处理了这个uni.scss,使得每个scss文件都被注入这个uni.scss,达到全局可用的效果。如果开发者想要less、stylus的全局使用,需要在vue.config.js中自行配置webpack策略。

基本上小项目需要用的几个主要文件就这么几个,如果想了解其他的,请自行查阅。

目录详解

目前我们会用到的就两个:pages 和 static

pages 用来放置我们的页面文件,static 用来放置静态资源,需要注意的是static 目录下的 js 文件不会被编译,如果里面有 es6 的代码,不经过转换直接运行,在手机设备上会报错。cssless/scss 等资源同样不要放在 static 目录下,建议这些公用的资源放在 common 目录(自己新建)下。

如果需要引入资源的话,使用绝对路径时,根目录就是 src/ 比如我们要引入 pages 下的 index 页面,那么路径就是:pages/index/index.vue 后缀可省略,且最前方不可以写 /

全局配置

打开 pages.json ,你会看到如下的配置:

全局配置

用于设置应用的状态栏、导航条、标题、窗口背景色等。

具体配置请看下表:

属性 类型 默认值 描述 平台差异说明
navigationBarBackgroundColor HexColor #F7F7F7 导航栏背景颜色(同状态栏背景色) APP与H5为#F7F7F7,小程序平台请参考相应小程序文档
navigationBarTextStyle String white 导航栏标题颜色及状态栏前景颜色,仅支持 black/white
navigationBarTitleText String 导航栏标题文字内容
navigationStyle String default 导航栏样式,仅支持 default/custom。custom即取消默认的原生导航栏,需看使用注意 微信小程序 7.0+、百度小程序、H5、App(2.0.3+)
backgroundColor HexColor #ffffff 下拉显示出来的窗口的背景色 微信小程序
backgroundTextStyle String dark 下拉 loading 的样式,仅支持 dark / light 微信小程序
enablePullDownRefresh Boolean false 是否开启下拉刷新,详见页面生命周期
onReachBottomDistance Number 50 页面上拉触底事件触发时距页面底部距离,单位只支持px,详见页面生命周期
backgroundColorTop HexColor #ffffff 顶部窗口的背景色(bounce回弹区域) 仅 iOS 平台
backgroundColorBottom HexColor #ffffff 底部窗口的背景色(bounce回弹区域) 仅 iOS 平台
titleImage String 导航栏图片地址(替换当前文字标题),支付宝小程序内必须使用https的图片链接地址 支付宝小程序、H5、APP
transparentTitle String none 导航栏整体(前景、背景)透明设置。支持 always 一直透明 / auto 滑动自适应 / none 不透明 支付宝小程序、H5、APP
titlePenetrate String NO 导航栏点击穿透 支付宝小程序、H5
pageOrientation String portrait 横屏配置,屏幕旋转设置,仅支持 auto / portrait / landscape 详见 响应显示区域变化 App 2.4.7+、微信小程序
animationType String pop-in 窗口显示的动画效果,详见:窗口动画 App
animationDuration Number 300 窗口显示动画的持续时间,单位为 ms App
app-plus Object 设置编译到 App 平台的特定样式,配置项参考下方 app-plus App
h5 Object 设置编译到 H5 平台的特定样式,配置项参考下方 H5 H5
mp-alipay Object 设置编译到 mp-alipay 平台的特定样式,配置项参考下方 MP-ALIPAY 支付宝小程序
mp-weixin Object 设置编译到 mp-weixin 平台的特定样式 微信小程序
mp-baidu Object 设置编译到 mp-baidu 平台的特定样式 百度小程序
mp-toutiao Object 设置编译到 mp-toutiao 平台的特定样式 字节跳动小程序
mp-qq Object 设置编译到 mp-qq 平台的特定样式 QQ小程序
usingComponents Object 引用小程序组件,参考 小程序组件
renderingMode String 同层渲染,webrtc(实时音视频) 无法正常时尝试配置 seperated 强制关掉同层 微信小程序

官方提示

咱也用不到那么多。看看就行。

新建页面和导航栏

创建

在 pages 目录下创建一个新页面,如:

创建新的页面

页面的 vue 文件为了规范开发,请放在单独的文件夹中

然后在 pages.json 文件中注册页面:

注册页面

需要注意的是一定要语法规范,少一个多一个逗号都不行,会报错。

创建导航栏:

导航栏配置

导航栏的 list 数组必须大于等于两个小于等于五个,多了或者少了都会无法使用,请注意这一点

配置详解

pages

pages

  • path :顾名思义,就是页面的路径,格式如图,前面不能加 / 谨记
  • style :页面相关的样式配置
  • navigationBarTitleText:页面顶部栏的名称

还有很多自定义配置,如下表:

属性 类型 默认值 描述 平台差异说明
navigationBarBackgroundColor HexColor #000000 导航栏背景颜色(同状态栏背景色),如”#000000”
navigationBarTextStyle String white 导航栏标题颜色及状态栏前景颜色,仅支持 black/white
navigationBarTitleText String 导航栏标题文字内容
navigationBarShadow Object 导航栏阴影,配置参考下方 导航栏阴影
navigationStyle String default 导航栏样式,仅支持 default/custom。custom即取消默认的原生导航栏,需看使用注意 微信小程序 7.0+、百度小程序、H5、App(2.0.3+)
disableScroll Boolean false 设置为 true 则页面整体不能上下滚动(bounce效果),只在页面配置中有效,在globalStyle中设置无效 微信小程序(iOS)、百度小程序(iOS)
backgroundColor HexColor #ffffff 窗口的背景色 微信小程序、百度小程序、字节跳动小程序
backgroundTextStyle String dark 下拉 loading 的样式,仅支持 dark/light
enablePullDownRefresh Boolean false 是否开启下拉刷新,详见页面生命周期
onReachBottomDistance Number 50 页面上拉触底事件触发时距页面底部距离,单位只支持px,详见页面生命周期
backgroundColorTop HexColor #ffffff 顶部窗口的背景色(bounce回弹区域) 仅 iOS 平台
backgroundColorBottom HexColor #ffffff 底部窗口的背景色(bounce回弹区域) 仅 iOS 平台
titleImage String 导航栏图片地址(替换当前文字标题),支付宝小程序内必须使用https的图片链接地址 支付宝小程序、H5
transparentTitle String none 导航栏透明设置。支持 always 一直透明 / auto 滑动自适应 / none 不透明 支付宝小程序、H5、APP
titlePenetrate String NO 导航栏点击穿透 支付宝小程序、H5
app-plus Object 设置编译到 App 平台的特定样式,配置项参考下方 app-plus App
h5 Object 设置编译到 H5 平台的特定样式,配置项参考下方 H5 H5
mp-alipay Object 设置编译到 mp-alipay 平台的特定样式,配置项参考下方 MP-ALIPAY 支付宝小程序
mp-weixin Object 设置编译到 mp-weixin 平台的特定样式 微信小程序
mp-baidu Object 设置编译到 mp-baidu 平台的特定样式 百度小程序
mp-toutiao Object 设置编译到 mp-toutiao 平台的特定样式 字节跳动小程序
mp-qq Object 设置编译到 mp-qq 平台的特定样式 QQ小程序
usingComponents Object 引用小程序组件,参考 小程序组件 App、微信小程序、支付宝小程序、百度小程序

页面中配置项会覆盖 globalStyle 中相同的配置项,这一点要注意哦

tabBar

属性说明:

属性 类型 必填 默认值 描述 平台差异说明
color HexColor tab 上的文字默认颜色
selectedColor HexColor tab 上的文字选中时的颜色
backgroundColor HexColor tab 的背景色
borderStyle String black tabbar 上边框的颜色,可选值 black/white App 2.3.4+ 支持其他颜色值
blurEffect String none iOS 高斯模糊效果,可选值 dark/extralight/light/none(参考:使用说明 App 2.4.0+ 支持
list Array tab 的列表,详见 list 属性说明,最少2个、最多5个 tab
position String bottom 可选值 bottom、top top 值仅微信小程序支持
fontSize String 10px 文字默认大小 App 2.3.4+
iconWidth String 24px 图标默认宽度(高度等比例缩放) App 2.3.4+
spacing String 3px 图标和文字的间距 App 2.3.4+
height String 50px tabBar 默认高度 App 2.3.4+
midButton Object 中间按钮 仅在 list 项为偶数时有效 App 2.3.4+

其中 list 接收一个数组,数组中的每个项都是一个对象,其属性值如下:

属性 类型 必填 说明
pagePath String 页面路径,必须在 pages 中先定义
text String tab 上按钮文字,在 App 和 H5 平台为非必填。例如中间可放一个没有文字的+号图标
iconPath String 图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px,当 postion 为 top 时,此参数无效,不支持网络图片,不支持字体图标
selectedIconPath String 选中时的图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px ,当 postion 为 top 时,此参数无效

更具体的配置和注意事项这里不多做赘述,请自行查阅,下面来展示示例。

示例

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
},{
"path": "pages/me/me",
"style": {
"navigationBarTitleText": "me"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"color":"",
"selectedColor":"",
"backgroundColor":"",
"borderStyle":"white",
"position":"bottom",
"list": [
{
"text":"首页",
"pagePath":"pages/index/index",
"iconPath":"static/tabBar/home.png",
"selectedIconPath":"static/tabBar/homeActive.png"
},{
"text":"我的",
"pagePath":"pages/me/me",
"iconPath":"static/tabBar/me.png",
"selectedIconPath":"static/tabBar/meActive.png"
}
]
}
}

me.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<template>
<view>
{{msg}}
</view>
</template>

<script>
export default {
data() {
return {
msg: 'Hello'
}
},
onLoad() {

},
methods: {

}
}
</script>

<style>

</style>

注意,图标文件需要自己去放置到指定位置,最初始的页面必须包含一个 templateview 父标签

效果:

首页

我的

这样,最基础的创建导航栏和新建页面就完成啦,是不是很简单呢,嘻嘻

今天就到这里,有空更新语法~赛哟啦啦