前言

文章记录uniapp知识点


uniapp项目目录

  1. pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等
  2. manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。
  3. App.vue是我们的跟组件,所有页面都是在App.vue下进行切换的,是页面入口文件,可以调用应用的生命周期函数。
  4. main.js是我们的项目入口文件,主要作用是初始化vue实例并使用需要的插件。
  5. uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量预置。
  6. unpackage 就是打包目录,在这里有各个平台的打包文件
  7. pages 所有的页面存放目录
  8. static 静态资源目录,例如图片等
  9. components 组件存放目录

全局配置和页面配置

全局配置globalStyle

下方为常用的配置 文档地址

属性 类型 默认值 描述
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
1
2
3
4
// 通过globalStyle进行全局配置
// 注意:backgroundColor需要开启下拉才可以配置(下拉显示出来的窗口的背景色,微信小程序支持)

// 有h5、mp-weixin、app-plus等平台特定样式配置(具体用法还未使用)

pages配置

属性 类型 描述
path String 配置页面路径
style Object 配置页面窗口表现,配置项参考
1
2
// pages数组数组中第一项表示应用启动页
// 配置会覆盖全局,并且也有h5等特定样式配置

配置tabbar

注意:当设置 position 为 top 时,将不会显示 icon

tabBar 中的 list 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。


condition启动模式配置

启动模式配置,仅开发期间生效,用于模拟直达页面的场景,如:小程序转发后,用户点击所打开的页面。

属性说明:

属性 类型 是否必填 描述
current Number 当前激活的模式,list节点的索引值
list Array 启动模式列表

list说明:

属性 类型 是否必填 描述
name String 启动模式名称
path String 启动页面路径
query String 启动参数,可在页面的onLoad函数里获得

组件

1
2
3
4
5
6
7
// text 组件相当于行内标签、在同一行显示

// <image> 组件默认宽度 300px、高度 225px;
// src仅支持相对路径、绝对路径,支持 base64 码;
// 页面结构复杂,css样式太多的情况,使用 image 可能导致样式生效较慢,
// 出现 “闪一下” 的情况,此时设置 image{will-change: transform} ,可优化此问题。
// 图片mode属性剪切aspectFit、aspectFill常用

uni-app的css样式

  1. rpx 即响应式px,一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准,750rpx恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大。
  2. 使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束
  3. 支持基本常用的选择器class、id、element等
  4. 在 uni-app 中不能使用 * 选择器。
  5. page 相当于 body 节点
  6. 定义在 App.vue 中的样式为全局样式,作用于每一个页面。在 pages 目录下 的 vue 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 App.vue 中相同的选择器。
  7. uni-app 支持使用字体图标,使用方式与普通 web 项目相同,需要注意以下几点:
  8. 字体文件小于 40kb,uni-app 会自动将其转化为 base64 格式;
  9. 字体文件大于等于 40kb, 需开发者自己转换,否则使用将不生效;
  10. 字体文件的引用路径推荐使用以 @ 开头的绝对路径。 `@font-face { font-family: test1-icon; src: url(‘@/static/iconfont.ttf’); }`
  11. 如何使用scss或者less(编辑器直接安装插件)

uni-app的生命周期

应用的生命周期

函数名 说明
onLaunch 当uni-app初始化完成时触发(全局只触发一次)
onShow 当uni-app启动,或从后台进入前台显示
onHide 当uni-app从前台进入后台
onError 当uni-app报错时触发

页面的生命周期

函数名 说明
onLoad 监听页面加载,其参数为上个页面传递的数据,参数类型为Object(用于页面传参)
onShow 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
onReady 监听页面初次渲染完成。
onHide 监听页面隐藏
onUnload 监听页面卸载

开启下拉刷新

1
2
3
4
5
6
7
// pages.json配置pages节点,在 style 选项中开启 enablePullDownRefresh
// 监听
onPullDownRefresh () {}
// 关闭下拉刷新
uni.stopPullDownRefresh()
// 通过调用uni.startPullDownRefresh方法来开启下拉刷新
uni.startPullDownRefresh()

上拉加载

1
2
3
// pages.json里pages的style中配置onReachBottomDistance可设置距离底部加载距离,默认为50px
// 通过onReachBottom监听到触底的行为
onReachBottom () {}

部分api

1
2
3
4
5
6
7
8
// 发送请求
uni.request({})

// 本地缓存
uni.setStorageSync()

// 预览图片
uni.previewImage({})

条件语句

条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。

1
2
3
4
#ifdef:if defined 仅在某平台存在
#ifndef:if not defined 除了某平台均存在
%PLATFORM%:平台名称
#endif 结尾

代码演示

1
2
3
4
5
6
7
8
9
10
<!-- #ifdef H5 -->
<view>
h5页面会显示
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view>
微信小程序会显示
</view>
<!-- #endif -->
1
2
3
4
5
6
7
8
onLoad () {
//#ifdef MP-WEIXIN
console.log('微信小程序')
//#endif
//#ifdef H5
console.log('h5页面')
//#endif
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* #ifdef H5 */
view{
height: 100px;
line-height: 100px;
background: red;
}
/* #endif */
/* #ifdef MP-WEIXIN */
view{
height: 100px;
line-height: 100px;
background: green;
}
/* #endif */

uni中的导航跳转

1
2
3
4
5
6
7
8
9
10
11
// 声明式导航
<navigator url="/pages/about/about" hover-class="navigator-hover">
<button type="default">跳转到关于页面</button>
</navigator>
// 跳转到tabbar页面,添加open-type="switchTab"属性

// --------------

// 编程式导航,url相对和绝对都可以
uni.navigateTo({})
uni.switchTab({})

组件

1
2
3
4
// 组件的生命周期和vue的一致
//uni-app的全局事件总线
uni.$emit('update',{msg:'页面更新'})
uni.$on('update',function(data){})

项目

封装request请求

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
// 封装get请求
const baseUrl = "xxx"
export const myRequest = (options)=>{
return new Promise((resolve,reject)=>{
uni.request({
method: options.method,
data: options.data,
url: baseUrl+options.url,
success(res) {
if(res.data.status !== 0) {
return uni.showToast({
title: '获取数据失败'
})
}
resolve(res)
},
fail(err) {
uni.showToast({
title: '获取数据失败'
})
reject(err)
}
})
})
}

// 在main.js中导入并挂载到全局
import { myRequest } from './util/api.js'
Vue.prototype.$myRequest = myReques

uniapp中vuex刷新数据保留

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// 方案1
//在页面刷新时将vuex里的信息保存到Storage里
window.addEventListener("beforeunload", () => {
uni.setStorageSync("userComMsg", JSON.stringify(this.$store.state));
});
//在页面加载时读取Storage里的状态信息
if (uni.getStorageSync("userComMsg")) {
Object.assign(
this.$store.state,
JSON.parse(uni.getStorageSync("userComMsg"))
);
//使用后清除内存
setTimeout(function () {
uni.removeStorageSync("userComMsg");
}, 300);

}

// ---------------------

// 方案2
// 使用拦截器uni.addInterceptor(STRING, OBJECT)
// 页面白名单
const whiteList = [
'/',
'/pages/login/index',
'/pages/index/index',
'/pages/category/index',
]

function hasPermission (url) {
// 在白名单中或有token,直接跳转
if(whiteList.indexOf(url) !== -1 || store.getters.access_token) {
return true
}
return false
}

uni.addInterceptor('navigateTo', {
// 页面跳转前进行拦截, invoke根据返回值进行判断是否继续执行跳转
invoke (e) {
if(!hasPermission(e.url)){
uni.reLaunch({
url: '/pages/login/index'
})
return false
}
return true
},
success (e) {
// console.log(e)
}
})

uni.addInterceptor('switchTab', {
// tabbar页面跳转前进行拦截
invoke (e) {
if(!hasPermission(e.url)){
uni.reLaunch({
url: '/pages/login/index'
})
return false
}
return true
},
success (e) {
// console.log(e)
}
})

// 拦截uni.switchTab本身没有问题。微信小程序端点击tabbar的底层逻辑并不是触发uni.switchTab。
// 解决方案是在tabbar页面的页面生命周期onShow中处理。

// ------------------------

// 方案3
// 在APP.vue的onLaunch中(每次刷新后就会触发)
// 获取token
uni.getStorage({
key: 'token',
success: ({ data }) => {
this.$store.commit('login', data)
if(this.$store.state.userInfo) return // 如果有用户信息则不用重新获取
this.$u.get('/api/user').then(({ data }) => {
this.$store.commit('userInfo', data) // 设置用户信息
}).catch(() => {
this.$store.commit('logOut') // 退出
})
}
})

原生插件的使用

  1. 插件市场添加插件,注意购买的包名选择当前的项目
  2. manifest.js配置APP原生插件,注意高德地图插件定位和maps可能会有冲突
  3. 选择运行-制作自定义基座-运行基座选择未自定义-运行
  4. 安装的证书获取:https://dev.dcloud.net.cn
  5. 选择对应的应用-应用证书股管理-获取证书