uni-app
写下博客主要用来分享知识内容,便于自我复习和总结。
如有错误之处,望各位指出。
在学习uni-app的内容前,最好要有一定的Vue基础,但不一定要了解原生小程序。
uni-app介绍
uni-app是一个使用Vue.js开发所有前端应用的框架。开发者编写一套代码,就可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台。
之前笔者在学习时,选择使用mpvue去开发微信小程序,当时感觉mpvue真不错。但后来发现mpvue确实存在一系列兼容性问题,而且貌似mpvue内的很多内容已经不维护了?但说回正题,现在接触到uni-app之后,笔者直接光速沦陷,因为uni-app和HBuiderX是真的好用:uni-app使用起来比较简单,HBuiderX内置了很多实用插件。界面和功能十分友好,它还可以做到一套代码,运行到多个平台,而且是自带的一键式操作。除此以外,即使不跨端,uni-app也绝对是更好的小程序开发框架。
HBuiderX可从官网免费下载,且下载操作很简单:HBuiderX官网
想了解更多uni-app内容,或者在遇到一些问题时,想找到解决方案,直接参照官网即可:uni-app官网
项目搭建
在HBuilderX内,新建项目,选择uni-app。其中的模板可以根据项目的需求选用。
笔者通常会在这里选择uni-ui项目,这样就可以使用更多扩展组件了。当然,就算不在这里选择使用uni-ui,后续在项目里也还可以通过npm导入uni-ui。
这个uni-ui是DCloud提供的一个跨端ui库,它是基于vue组件的、flex布局的、无dom的跨全端ui框架。(uni-ui不包括基础组件,它是基础组件的补充)
具体的使用都可以在官网找到:uni-ui
建好项目之后,想要运行就直接打开上方菜单栏中的运行即可。里面会有很多种运行方式,点击就可一键启动,十分方便。但对于每种方式需要确保有运行条件。
1、对于运行到浏览器,需要在本机上有相应浏览器。如果确定本机上有相应浏览器,却未检测到,它就会跳转到运行配置,我们手动配置好安装路径即可。
2、对于运行到内置浏览器,我们就不需要额外安装浏览器,HBuilderX里会有内置浏览器。
我们只要去 工具 -> 插件安装 中安装即可,里面有内置浏览器,内置终端等。其他有关插件,根据自己的需求去插件市场下载即可。
3、对于运行到手机或模拟器,如果我们想在真机上测试效果,首先使用usb数据线连接自己的手机,然后将手机设置为开发者模式中的USB调试模式。(如果不知道如何开启USB调试模式请根据自己手机情况,百度查询)
调整好了之后,使用HBuilderX的运行 - 运行到手机或模拟器 =》这时上面就会显示手机(一定是开启了USB调试模式才会检测出手机)
选择自己的手机后,HBuilderX就会在手机上自动安装一个HbuilderAPP,用于真机调试。
如果不想真机调试,在里面会看到 配置手机模拟器的教程 或者 用chrome调试Android应用。
4、对于运行到小程序模拟器,因为目前只接触过微信开发者工具,在这里就以它为例。(在这里就不介绍,如何创建一个微信个人开发者帐号了,直接去微信公众平台申请即可:微信公众平台。开发其它平台小程序,就去各自平台查找相关说明吧。对于微信而言,一定需要申请帐号开发权限)
我们选择本机的开发者工具后,第一次会检测不到开发者工具。这时它会跳转到配置文件,我们为其配置路径即可。
然后,我们打开项目的manifest.json文件,需要去里面为各个小程序配置相关信息。
以微信小程序为例,在这里一定需要配置AppID。这个AppID我们需要去官网查询获取:查询方式
等我们获取了之后,打开微信开发者工具时(如果未登录还需要先登录自己的帐号噢),在界面右上角 或者 >> 里有个详情,之后就可以在这里看到自己的APPID了。(这是在微信开发者工具中导入或新建了一个项目后才有的界面)
随后,还要确保设置中的安全设置的服务端口打开。
目录结构
(以上项目目录结构不是默认结构,笔者有自己新建的文件夹)
如果是默认uni-app模板项目,是没有components的。选择了uni-ui模板项目 或 其它模板项目时,相关新增的所有组件就会放到components里。如果我们只想按需获取,那就把里面的多余组件删掉即可。除此以外,按照个人习惯,如果项目中还要抽取公共组件,笔者通常会把公共组件也放入其中(当然,也可以自己在新建文件夹)。
pages
存放项目的页面。
static
存放项目静态资源,比如images。
store
存放vuex。
unpackage
存放打包后的文件,新建的项目是没有的。(使用微信开发者工具运行后,也会出现此文件夹)
对于打包后的文件,还需要说的是:如果打包后,相关组件或者图片失去了效果,可能是打包后的相关内容的引用路径出现了改变,导致错误。一旦出现类似错误,大家可以留意一下。
App.vue
是项目的根组件,所有页面都是在App.vue
下进行切换的,是页面的入口文件,可以调用应用的生命周期函数。
main.js
是项目的入口文件,主要作用是初始化vue
实例并使用需要的插件。
manifest.json
文件是应用的配置文件,用于指定应用的名称、图标、权限等。
pages.json
文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等。
uni.scss
文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss
文件里预置了一批scss变量预置。
App.vue 和 main.js
对于App.vue、main.js 和 在Vue里的用法类似,现在在默认模板项目的基础上,把一些常用的改变内容记录如下:
App.vue
<script>
import store from '@/store/index.js'
export default {
onLaunch: function() {
console.log('App Launch');
// 每次打开小程序都进入该生命周期(常用:初始化相关信息)
store.dispatch('login');
console.log(store.state.isLogin);
},
onShow: function() {
console.log('App Show');
},
onHide: function() {
console.log('App Hide');
}
};
</script>
<style>
/*自建common文件夹,存放每个页面公共css */
@import url("/common/icons/iconfont.css"); /*很关键!导入iconfont时,要使用url!深坑勿踩!*/
@import "/common/styles/test.scss";
/* 解决头条小程序组件内引入字体不生效的问题 */
/* #ifdef MP-TOUTIAO */
@font-face {
font-family: uniicons;
src: url('/static/uni.ttf');
}
/* #endif */
</style>
main.js
import Vue from 'vue'
import App from './App'
/* 例:导入Vuex store */
import store from './store'
Vue.prototype.$store = store
/* 例:导入uView */
import uView from "uview-ui";
Vue.use(uView);
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App,
store
})
app.$mount()
store里的index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
isLogin: false,
},
mutations: {
loginSuccess(state){
state.isLogin = true;
},
},
actions:{
login({ commit, state }){
if(state.isLogin){
console.warn("已经登录,不能重复登录!");
return;
}
commit('loginSuccess');
},
},
})
export default store
如果您阅读到这里,真的没学过Vue,建议还是先系统的学习一下Vue,可以参考我的专栏:Vue。在这里,Vuex,App.vue,main.js中,各部分的作用和内容,就不在这里赘述了。如果无心学习Vue,这么记当然也可以。具体的生命周期,之后还会提到。
manifest.json
在之前配置各种相关内容时,自动跳转到的配置信息界面,就是这个json文件。如果使用HBuiderX打开,它会是这种界面信息,而如果是用其它开发工具打开,它会是一串代码,但内容是相同的。(当然,你可以考虑从其它开发工具修改它)
对比:
在最后发行打包的时候,这个文件的内容还需要配置一些内容,比如App图标配置,广告配置等。网上也能找到相关教程,在这里就不介绍了。
uni.scss
具体的说明,在文件中已经说明,
因此,我们想自定义主题的时候,就可以在这里设置相关颜色信息配置。
pages.json
用于设置应用的状态栏、导航条、标题、窗口背景色等。
在这里就简单介绍几个常用的,其它具体的看文档作出修改即可,详细文档
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
navigationBarBackgroundColor | HexColor | #F7F7F7 | 导航栏背景颜色(同状态栏背景色) |
navigationBarTextStyle | String | white | 导航栏标题颜色及状态栏前景颜色,仅支持 black/white |
navigationBarTitleText | String | 导航栏标题文字内容 | |
backgroundColor | HexColor | #ffffff | 窗口的背景色 |
backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light |
enablePullDownRefresh | Boolean | false | 是否开启下拉刷新,详见页面生命周期。 |
onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位只支持px,详见页面生命周期 |
{
"pages": [{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-ui基础项目"
}
}],
"globalStyle": { // 全局配置:如果pages页面配置有同名配置,全局配置将失效
"navigationBarTextStyle": "white",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#007AFF",
"backgroundColor": "#70B575", // 窗口背景色,当页面下拉时才能看到
"enablePullDownRefresh": true, // 开启下拉(只有在小程序开发工具才能看到效果)
"backgroundTextStyle": "light"
}
}
(小程序下拉刷新)
(h5下拉刷新)
然后要说的是,如果我们开发的是小程序,因为小程序各平台不同,有些用法还是会有差异的,如果遇到问题建议查阅官方文档!除此以外,开发小程序还是建议用各小程序开发工具,笔者之前只是从网页看效果,但是很多效果都看不到,最后后知后觉发现少做了很多功能。
简单对比:
(小程序)
(h5页面)
页面配置
现在我们新建了一个页面(组件),我们接下来看如何为其进行配置。
我们在message里随便写点内容:
<template>
<view>新建内容</view>
</template>
<script>
</script>
<style>
</style>
然后去page.json中配置:
{
"pages": [// pages数组中第一项表示应用启动页
{
"path": "pages/message/message"
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-ui基础项目"
}
}
],
"globalStyle": { // 全局配置:如果页面配置有同名配置,全局配置将失效
"navigationBarTextStyle": "white",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#007AFF",
"backgroundColor": "#70B575", // 窗口背景色,当页面下拉时才能看到
"enablePullDownRefresh": true, // 开启下拉(只有在小程序开发工具才能看到效果)
"backgroundTextStyle": "light"
}
}
看效果:
注意: pages数组中第一项表示应用启动页。(页面跳转之后再聊)
说明:虽然小程序暂时没法跳转页面,但是在浏览器中我们可以通过修改路径,进入不同的页面。(之前虽然说过,页面看效果要比小程序少了些功能,但是如果是项目开发,我们不可能等其它同事将上一页面开发完,再去做跳转后的页面,所以用浏览器直接进入跳转后页面,也是必要的)
而且还出现了回退功能,点击就可回到上一路径。
然后pages里每个页面的style配置和全局配置,部分内容还是有区别的,详细的配置就不再演示了,因为内容很多,而且配置也没什么难度,大家需要改变时,参考官方文档即可。
在配置里,还需要介绍一个需要注意的内容:我们可以为其设置编译到不同平台的特定样式。
以h5刚才的下拉刷新为例:
{
"pages": [// pages数组中第一项表示应用启动页
{
"path": "pages/message/message",
"style":{
"navigationBarTitleText": "信息页",
"h5":{
"pullToRefresh":{
"color": "#7D26CD"
}
}
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-ui基础项目"
}
}
],
"globalStyle": { // 全局配置:如果页面配置有同名配置,全局配置将失效
"navigationBarTextStyle": "white",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#007AFF",
"backgroundColor": "#70B575", // 窗口背景色,当页面下拉时才能看到
"enablePullDownRefresh": true, // 开启下拉(只有在小程序开发工具才能看到效果)
"backgroundTextStyle": "light"
}
}
看效果:
tabbar的配置
如果应用是一个多 tab 应用,可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页。官方文档
Tips
- 当设置 position 为 top 时,将不会显示 icon,并且 top 值仅微信小程序支持
- tabBar 中的 list 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。
属性说明:
属性 | 类型 | 必填 | 默认值 | 描述 | 平台差异说明 |
---|---|---|---|---|---|
color | HexColor | 是 | tab 上的文字默认颜色 | ||
selectedColor | HexColor | 是 | tab 上的文字选中时的颜色 | ||
backgroundColor | HexColor | 是 | tab 的背景色 | ||
borderStyle | String | 否 | black | tabbar 上边框的颜色,仅支持 black/white | App 2.3.4+ 支持其他颜色值 |
list | Array | 是 | tab 的列表,详见 list 属性说明,最少2个、最多5个 tab | ||
position | String | 否 | bottom | 可选值 bottom、top | top 值仅微信小程序支持 |
其中 list 接收一个数组,数组中的每个项都是一个对象,其属性值如下:
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
pagePath | String | 是 | 页面路径,必须在 pages 中先定义 |
text | String | 是 | tab 上按钮文字,在 5+APP 和 H5 平台为非必填。例如中间可放一个没有文字的+号图标 |
iconPath | String | 否 | 图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px,当 postion 为 top 时,此参数无效,不支持网络图片,不支持字体图标 |
selectedIconPath | String | 否 | 选中时的图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px ,当 postion 为 top 时,此参数无效 |
例:
{
"pages": [// pages数组中第一项表示应用启动页
{
"path": "pages/message/message",
"style":{
"navigationBarTitleText": "信息页",
"h5":{
"pullToRefresh":{
"color": "#7D26CD"
}
}
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-ui基础项目"
}
}
],
"globalStyle": { // 全局配置:如果页面配置有同名配置,全局配置将失效
"navigationBarTextStyle": "white",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#007AFF",
"backgroundColor": "#70B575", // 窗口背景色,当页面下拉时才能看到
"enablePullDownRefresh": true, // 开启下拉(只有在小程序开发工具才能看到效果)
"backgroundTextStyle": "light"
},
"tabBar": {
"color": "#A0522D",
"selectedColor": "#B3EE3A",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"text": "首页",
"pagePath":"pages/index/index",
"iconPath":"static/tabs/re.png",
"selectedIconPath":"static/tabs/re_c.png"
},
{
"text": "信息",
"pagePath":"pages/message/message",
"iconPath":"static/tabs/re.png",
"selectedIconPath":"static/tabs/re_c.png"
}
]
}
}
看效果:
然后就是:当设置 position 为 top 时,将不会显示 icon,需要注意,top仅微信小程序支持
{
"pages": [// pages数组中第一项表示应用启动页
{
"path": "pages/message/message",
"style":{
"navigationBarTitleText": "信息页",
"h5":{
"pullToRefresh":{
"color": "#7D26CD"
}
}
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-ui基础项目"
}
}
],
"globalStyle": { // 全局配置:如果页面配置有同名配置,全局配置将失效
"navigationBarTextStyle": "white",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#007AFF",
"backgroundColor": "#70B575", // 窗口背景色,当页面下拉时才能看到
"enablePullDownRefresh": true, // 开启下拉(只有在小程序开发工具才能看到效果)
"backgroundTextStyle": "light"
},
"tabBar": {
"color": "#A0522D",
"selectedColor": "#B3EE3A",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"position": "top", // position
"list": [
{
"text": "首页",
"pagePath":"pages/index/index",
"iconPath":"static/tabs/re.png",
"selectedIconPath":"static/tabs/re_c.png"
},
{
"text": "信息",
"pagePath":"pages/message/message",
"iconPath":"static/tabs/re.png",
"selectedIconPath":"static/tabs/re_c.png"
}
]
}
}
看效果:
condition启动模式配置
在上面提到过,浏览器可以通过修改路径跳转页面,小程序是没办法这么做的,我们不可能每次都通过将页面放到pages数组中第一项来解决这个问题。那么除了之后添加事件跳转页面外,我们还可以通过对condition启动模式的配置来修改。
这个启动模式配置,仅开发期间生效,用于模拟直达页面的场景,如:小程序转发后,用户点击所打开的页面。
属性说明:
属性 | 类型 | 是否必填 | 描述 |
---|---|---|---|
current | Number | 是 | 当前激活的模式,list节点的索引值 |
list | Array | 是 | 启动模式列表 |
list说明:
属性 | 类型 | 是否必填 | 描述 |
---|---|---|---|
name | String | 是 | 启动模式名称 |
path | String | 是 | 启动页面路径 |
query | String | 否 | 启动参数,可在页面的 onLoad 函数里获得 |
{
"pages": [// pages数组中第一项表示应用启动页
{
"path": "pages/message/message",
"style":{
"navigationBarTitleText": "信息页",
"h5":{
"pullToRefresh":{
"color": "#7D26CD"
}
}
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-ui基础项目"
}
},
{
"path": "pages/detail/detail",
"style": {
"navigationBarTitleText": "详情页"
}
}
],
"globalStyle": { // 全局配置:如果页面配置有同名配置,全局配置将失效
"navigationBarTextStyle": "white",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#007AFF",
"backgroundColor": "#70B575", // 窗口背景色,当页面下拉时才能看到
"enablePullDownRefresh": true, // 开启下拉(只有在小程序开发工具才能看到效果)
"backgroundTextStyle": "light"
},
"tabBar": {
"color": "#A0522D",
"selectedColor": "#B3EE3A",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"text": "首页",
"pagePath":"pages/index/index",
"iconPath":"static/tabs/re.png",
"selectedIconPath":"static/tabs/re_c.png"
},
{
"text": "信息",
"pagePath":"pages/message/message",
"iconPath":"static/tabs/re.png",
"selectedIconPath":"static/tabs/re_c.png"
}
]
},
"condition": {
"current": 0,
"list": [
{
"name": "详情页",
"path": "pages/detail/detail",
"query": "id=80"
}
]
}
}
当我们配置好了condition之后,我们在微信小程序开发工具中就可以看到一个信息:
点击后,就可以快速进入页面了。
然后再说一下这里的query参数。比如我们要直接进入详情页,那在进入详情页前的某列表中,肯定需要传一个参数进来,以便在进入详情页后调接口,获取相关信息,这里的query就是这么一个作用(暂时用不上)。
开发规范简单介绍
为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app
约定了如下开发规范:
- 页面文件遵循 Vue 单文件组件 (SFC) 规范
- 组件标签靠近小程序规范,详见uni-app 组件规范
- 接口能力(JS API)靠近微信小程序规范,但需将前缀
wx
替换为uni
,详见uni-app接口规范 - 数据绑定及事件处理同
Vue.js
规范,同时补充了App及页面的生命周期 - 为兼容多端运行,建议使用flex布局进行开发