Appearance
配置
page.json
pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生 tabbar 等
在小程序中,定位权限申请等原属于
app.json的内容,在 uni-app 中是在manifest中配置
| 属性 | 类型 | 必填 | 描述 | | :------------ | :----------- | :----------- | :----------------------------- | --- | ------------------------ | | globalStyle | Object | 否 | 设置默认页面的窗口表现 | | pages | Object Array | 是 | 设置页面路径及窗口表现 | | easycom | Object | 否 | 组件自动引入规则 | | tabBar | Object | 否 | 设置底部 tab 的表现 | | condition | Object | 否 | 启动模式配置 | | subPackages | Object Array | 否 | 分包加载配置 | | preloadRule | Object | 否 | 分包预下载规则 | | workers | String | 否 | Worker 代码放置的目录 | | leftWindow | topWindow | rightWindow | Object | 否 | 大屏左 顶 右侧窗口 |
globalStyle
用于设置应用的状态栏、导航条、标题、窗口背景色等。
| 属性 | 类型 | 默认值 | 描述 | | :----------------------------- | :-------- | :----------- | :----------------------------------------------------------------------------------------------------------- | -------- | -------------------- | --------- | ------------ | --- | -------------- | | navigationBarBackgroundColor | HexColor | #F7F7F7 | 导航栏背景颜色(同状态栏背景色) | | navigationBarTextStyle | String | white | 导航栏标题颜色及状态栏前景颜色,仅支持 black/white | | navigationBarTitleText | String | | 导航栏标题文字内容 | | navigationStyle | String | default | 导航栏样式,仅支持 default/custom。custom:取消默认原生导航栏 | | backgroundColor | HexColor | #ffffff | 下拉窗口的背景色 | | backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light | | enablePullDownRefresh | Boolean | false | 是否开启下拉刷新 | | onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离(只支持px) | | backgroundColorTop | HexColor | #ffffff | 顶部窗口的背景色(bounce 回弹区域) | | backgroundColorBottom | HexColor | #ffffff | 底部窗口的背景色(bounce 回弹区域) | | titleImage | String | | 导航栏图片地址(替换当前文字标题) | | transparentTitle | String | none | 导航栏整体(前景、背景)透明设置。always: 一直透 auto:滑动自适应 none:不透明 | | titlePenetrate | String | NO | 导航栏点击穿透 | | pageOrientation | String | portrait | 横屏配置,屏幕旋转设置,仅支持 auto / portrait / landscape | | animationType | String | pop-in | 窗口显示的动画效果 | | animationDuration | Number | 300 | 窗口显示动画的持续时间(ms) | | app-plus | h5 | mp-alipay | mp-weixin | mp-baidu | mo-toutiao | mp-qq | Object | | 各平台特定样式 | | usingComponents | Object | | 引用小程序组件 | | renderingMode | String | | 同层渲染。webrtc(实时音视频) 无法正常时尝试配置 seperated 强制关掉同层 | | leftWindow | topWindow | rightWindow | Boolean | true | 是否显示 leftWindow | topWindow | rightWIndow | | rpxCalcMaxDeviceWidth | Number | 960 | rpx 最大设备宽度( px) | | rpxCalcBaseDeviceWidth | Number | 375 | rpx 基准设备宽度(px)
实际宽度超出 rpx 最大设备宽度时将按基准宽度计算,单位 px | | rpxCalcIncludeWidth | Number | 750 | rpx 计算特殊处理的值,始终按实际的设备宽度计算(rpx) | | maxWidth | Number | 1190 | 当浏览器可见区域宽度(px) |
Tips
- 支付宝小程序使用
titleImage时必须使用https的图片链接地址(真机有效,模拟器无效) globalStyle中设置的titleImage会覆盖掉pages->style内的设置文字标题- 使用
maxWidth时,页面内fixed元素需要使用--window-left,--window-right来保证布局位置正确>maxWidth,两侧留白<=maxWidth,页面铺满- 不同页面支持配置不同的 maxWidth
maxWidth = leftWindow(可选)+page(页面主体)+rightWindow(可选)
pages
通过 pages 节点配置应用由哪些页面组成
pages 节点接收一个数组,每个项都是一个对象
| 属性 | 类型 | 描述 |
|---|---|---|
path | String | 配置页面路径 |
style | Object | 配置页面窗口表现 |
Tips
- pages 节点的第一项为应用入口页(即首页)
- 应用中新增/减少页面,都需要对 pages 数组进行修改
- 文件名不需要写后缀,框架会自动寻找路径下的页面资源
style
设置每个页面的状态栏、导航条、标题、窗口背景色等
页面中配置项会覆盖 globalStyle 中相同的配置项
| 属性 | 类型 | 默认值 | 描述 | | :----------------------------- | :-------- | :----------- | :----------------------------------------------------------------------------- | -------- | --------------------------------- | --------- | ------------ | --- | -------------- | | navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色(同状态栏背景色) | | navigationBarTextStyle | String | white | 导航栏标题颜色及状态栏前景颜色,仅支持 black/white | | navigationBarTitleText | String | | 导航栏标题文字内容 | | navigationBarShadow | Object | | 导航栏阴影 | | navigationStyle | String | default | 导航栏样式,仅支持 default/custom。 | | disableScroll | Boolean | false | 设置为 true 则页面整体不能上下滚动(bounce 效果*globalStyle中设置无效* | | backgroundColor | HexColor | #ffffff | 窗口的背景色 | | backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark/light | | enablePullDownRefresh | Boolean | false | 是否开启下拉刷新 | | onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位只支持 px | | backgroundColorTop | HexColor | #ffffff | 顶部窗口的背景色(bounce 回弹区域) | | backgroundColorBottom | HexColor | #ffffff | 底部窗口的背景色(bounce 回弹区域) | | titleImage | String | | 导航栏图片地址(替换当前文字标题) | | transparentTitle | String | none | 导航栏透明设置。支持 always / auto / none | | titlePenetrate | String | NO | 导航栏点击穿透 | | app-plus | h5 | mp-alipay | mp-weixin | mp-baidu | mo-toutiao | mp-qq | Object | | 各平台特定样式 | | usingComponents | Object | | 引用小程序组件 | | leftWindow | topWindow | rightWindow | Boolean | true | 当前页面是否显示leftWindow | topWindow | rightWindow | | maxWidth | Number | 1190 | 单位 px |
topWindow | leftWindow | rightWindow:可解决宽屏适配问题
自定义导航栏
以下两种:原生导航栏不显示
navigationStyle设为customtitleNView设为false
Tips
- 非 H5 端,手机顶部状态栏区域会被页面内容覆盖。状态栏高度的 css 变量
--status-bar-height
vue
<template>
<view>
<view class="status_bar">
<!-- 这里是状态栏 -->
</view>
<view> 状态栏下的文字 </view>
</view>
</template>
<style>
.status_bar {
height: var(--status-bar-height);
width: 100%;
}
</style>- 前端导航栏搭配原生下拉刷新
- 微信小程序下 iOS需要拉更长才能看到下拉刷新的三个点
- Android是从屏幕顶部下拉,无法从导航栏下方下拉
- 如果一定要从前端导航栏下拉,小程序下只能放弃原生下拉刷新,纯前端模拟,参考mescroll 插件,但这样很容易产生性能问题。
- 非 H5 端,前端导航盖不住原生组件
- 如果页面有
video、map、textarea(仅小程序)等原生组件,滚动时会覆盖住导航栏- 小程序,使用
cover-view来做导航栏,避免覆盖问题 - App,使用titleNView或subNVue,体验更好
- 小程序,使用
- 如果页面有
- 前端组件在渲染速度上不如原生导航栏
- 原生导航可以在动画期间渲染,保证动画期间不白屏
- 前端导航栏,在新窗体进入的动画期间可能会整页白屏,越低端的手机越明显
- 以上讨论的是前端自定义导航栏,在 App 侧,原生导航栏也提供了比小程序导航更丰富的自定义性
titleNView:给原生导航栏提供更多配置,包括自定义按钮、滚动渐变效果、搜索框等,详见titleNViewsubNView:使用 nvue 原生渲染,所有布局自己开发,具备一切自定义灵活度。详见subNVue
- 页面禁用原生导航栏后,改变状态栏的前景字体样式
- 可设置页面的
navigationBarTextStyle属性(只能设置为black或white) - 单独设置状态栏颜色,App 端可使用plus.navigator.setStatusBarStyle设置
- 低端 Android 手机(4.4)自身不支持设置状态栏前景色
- 可设置页面的
尽量使用原生导航
- App 和 H5 下,uni-app 提供了灵活的处理方案:titleNView、subNVue、或整页使用 nvue。
- 在小程序下,因为其自身的限制,没有太好的方案。
easycom
传统 vue 组件,需要安装、引用、注册,三个步骤后才能使用组件
easycom将其精简为一步
- 组件在项目的
components目录 - 并符合
components/组件名称/组件名称.vue目录结构
easycom打包后会自动剔除没有使用的组件
easycom是自动开启
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
autoscan | Boolean | true | 是否开启自动扫描,自动扫描符合条件的组件 |
custom | Object | - | 正则方式自定义组件匹配规则 |
Tips
easycom方式引入组件是局部引入- 组件名完全一致,
easycom引入的优先级低于手动引入(区分连字符形式与驼峰形式) - 考虑到编译速度,直接在
pages.json内修改easycom不会触发重新编译,需要改动页面内容触发。 easycom只处理vue组件。不处理后缀为.nvue的组件
tabBar
通过 tabBar 配置项指定一级导航栏,以及 tab 切换时显示的对应页
| 属性 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
color | HexColor | 是 | 文字默认颜色 | |
selectedColor | HexColor | 是 | 文字选中时的颜色 | |
backgroundColor | HexColor | 是 | 背景色 | |
borderStyle | String | 否 | black | 边框颜色,可选值 black/white |
blurEffect | String | 否 | none | iOS 高斯模糊效果dark/extralight/light/none |
list | Array | 是 | tab 列表(2-5) | |
position | String | 否 | bottom | 可选值 bottom、top |
fontSize | String | 否 | 10px | 文字默认大小 |
iconWidth | String | 否 | 24px | 图标默认宽度(高度等比例缩放) |
spacing | String | 否 | 3px | 图标和文字的间距 |
height | String | 否 | 50px | tabBar 默认高度 |
midButton | Object | 否 | 中间按钮 仅在 list 项为偶数时有效 |
Tips
position为 top 时,不会显示 iconlist是一个数组,只能配置2 - 5个 tab,按数组的顺序排序tabbar页面切换时,首次加载可能渲染不及时,可在tabbar页面onLoad生命周期里先弹出一个等待雪花tabbar页面展现后就保留在内存,再次切换tabbar页面,触发onShow,不触发onLoad。
list
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
pagePath | String | 是 | 页面路径,必须在 pages 中先定义 |
text | String | 是 | tab按钮文字,在 App 和 H5 平台为非必填 |
iconPath | String | 否 | 图片路径 |
selectedIconPath | String | 否 | 选中时的图片路径,同上 |
Tips
iconPath
- icon 大小限制为 40kb,建议尺寸为 81px * 81px
- 当 postion 为 top 时,此参数无效
- 不支持网络图片,不支持字体图标
midButton
| 属性 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
width | String | 否 | 80px | 中间按钮的宽度 tabBar 其它项为减去此宽度后平分,默认值为与其它项平分宽度 |
height | String | 否 | 50px | 中间按钮的高度 可大于 tabBar 高度,达到中间凸起的效果 |
text | String | 否 | 中间按钮的文字 | |
iconPath | String | 否 | 中间按钮的图片路径 | |
iconWidth | String | 否 | 24px | 图片宽度(高度等比例缩放) |
backgroundImage | String | 否 | 中间按钮的背景图片路径 |
midButton没有pagePath,需监听点击事件。监听点击事件 API:uni.onTabBarMidButtonTap
js api
| 函数 | 说明 | |
|---|---|---|
uni.setTabBarItem(OBJECT) | 设置 tabBar 某一项的内容 | |
uni.setTabBarStyle(OBJECT) | 设置 tabBar 的整体样式 | |
uni.hideTabBar(OBJECT) | 隐藏 tabBar | |
uni.showTabBar(OBJECT) | 显示 tabBar | |
uni.setTabBarBadge(OBJECT) | 为 tabBar 某项的右上角添加文本 | |
uni.showTabBarRedDot(OBJECT) | 显示 tabBar 某项的右上角的红点 | |
uni.hideTabBarRedDot(OBJECT) | 隐藏 tabBar 某项的右上角的红点 | |
uni.onTabBarMidButtonTap(CALLBACK) | 监听中间按钮点击事件 |
大部分操作 tabbar 的 API 需要在 tabbar 渲染后才能使用,避免在 tabbar 未初始化前使用
Tips
- 跳转到 tabbar 页面,只能使用uni.switchTab;使用navigator 组件跳转时必须设置open-type="switchTab"
- tabbar 的默认高度在不同平台不一样。App 端为 50px,与 H5 端一致。
- tabbar 在 H5 端是 div 模拟,属于前端屏幕窗口的一部分
- 在 tabbar 上方 10px 的按钮,
bottom: calc(var(--window-bottom) + 10px)
- 在 tabbar 上方 10px 的按钮,
- 先登录、后进入 tab 页面,不需要把登录页设为首页,首页仍然是 tabbar 页
- 前端弹出遮罩层挡不住 tabbar 的问题
- 跨端处理:动态隐藏 tabbar。
- App 端可以使用
plus.nativeObj.view 或subNVue做弹出和遮罩 - 底部原生图标分享菜单例子
- PC 宽屏上,当页面存在
topWindow或leftWindow或rightWindow等多窗体结构时,tabBar 自动隐藏(HBuilderX 2.9.9),使用 custom-tab-bar 组件 配置 tabBar 的位置
自定义tabbar
除了 H5 端,自定义tabBar的性能体验会低于原生tabBar
- 普通自定义
tabBar:使用 view 自行绘制 tabBar。- 页面是多页方式,切换 tabBar 将无法保持底部 tabBar 一直显示,这种情况建议单页方式
- 单页方式,复杂页面,应用性能会下降明显,需减少页面复杂度
- App 端,nvue 单页的性能会显著高于 vue 页面
- 微信小程序自定义
tabbar:微信提供一直基于 webview 自定义 tabBar 的方案。该功能体验不佳,不太推荐使用。 - 原生的
tabbar有且只有一个且在首页。二级页如需的 tab,需自行编写 view 来实现。一般二级页面更适合的导航是 segement 组件
Condition
启动模式配置,仅开发期间生效,用于模拟直达页面的场景
属性
| 属性 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
current | Number | 是 | 当前激活模式,list 节点的索引值 |
list | Array | 是 | 启动模式列表 |
list
| 属性 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
name | String | 是 | 启动模式名称 |
path | String | 是 | 启动页面路径 |
query | String | 否 | 启动参数,可在页面的 onLoad 函数里获得 |
subPackages
小程序有体积和资源加载限制,各家小程序平台提供了分包方式,优化小程序的下载和启动速度
主包:放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本
分包:根据pages.json的配置进行划分
小程序启动
- 默认会下载主包并启动主包内页面
- 当用户进入分包内某个页面时,会把对应分包自动下载
subPackages 节点接收一个数组,数组每一项都是应用的子包
| 属性 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
root | String | 是 | 子包的根目录 |
pages | Array | 是 | 子包由哪些页面组成,参数同 pages |
preloadRule
分包预载配置。
配置 preloadRule 后,在进入小程序某个页面时,由框架自动预下载可能需要的分包,提升进入后续分包页面时的启动速度
preloadRule 中,key 是页面路径,value 是进入此页面的预下载配置
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
packages | StringArray | 是 | 无 | 进入页面后预下载分包的 root 或 name。__APP__ 表示主包。 |
network | String | 否 | wifi | 在指定网络下预下载,可选值为:all(不限网络)、wifi(仅 wifi 下预下载) |
app 的分包,同样支持 preloadRule,但网络规则无效
? manifest.json
manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等
HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录
vue.config.js
vue.config.js 是一个可选的配置文件,项目根目录中存在这个文件,会被自动加载
仅 vue 页面生效
uni.scss
uni.scss是一个特殊文件,无需 import 即可在scss代码中使用
pages.json不支持scss,原生导航栏和 tabbar 的动态修改只能使用 js api
App.vue
App.vue是 uni-app 的主组件,所有页面都是在App.vue下进行切换
App.vue本身不是页面,不能编写视图元素
文件作用
- 调用应用生命周期函数
- 配置全局样式
- 配置全局存储
globalData
应用生命周期仅可在App.vue中监听,在页面监听无效
globalData
全局变量机制,全端通用。
vue
<script>
export default {
globalData: {
text: 'text'
}
}
</script>js方式: getApp().globalData.text = 'test'
在应用 onLaunch 时,getApp对象还未获取,暂时可以使用this.$scope.globalData获取globalData。
globalData数据绑定到页面上,可在页面onShow进行变量重赋值
由于weex 生命周期不支持 onShow
- 可利用监听 webview 的
addEventListenershow事件实现onShow效果 - 或直接使用 weex 生命周期中
beforeCreate
globalData是简单的全局变量
全局样式
同时有vue和nvue文件,全局样式的所有 css 会应用于所有文件,而 nvue 支持的 css 有限,编译器会在控制台报警,提示某些 css 无法在 nvue 中支持
需把 nvue 不支持的 css写在单独的条件编译
css
<style>
/* #ifndef APP-PLUS-NVUE */
@import './common/uni.css';
/* #endif*/
</style>框架接口
页面
getApp()
getApp() 函数用于获取当前应用实例,一般用于获取 globalData 。
js
const app = getApp()
console.log(app.globalData)- 不要在定义于
App()内的函数中,或调用App前调用getApp(),可以通过this.$scope获取对应的 app 实例 - 通过
getApp()获取实例之后,不要私自调用生命周期函数。 - v3 模式加速了首页
nvue的启动速度,在首页nvue中使用getApp()不一定可以获取App对象- v3 版本:
const app = getApp({allowDefault: true})用来获取原始的App对象,在首页对globalData等初始化
- v3 版本:
getCurrentPages()
getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。
| 方法 | 描述 | 平台说明 |
|---|---|---|
page.$getAppWebview() | 获取当前页面的 webview 对象实例 | App |
page.route | 获取当前页面的路由 |
getCurrentPages()仅用于展示页面栈,请勿修改页面栈
navigateTo,redirectTo只能打开非 tabBar 页面switchTab只能打开tabBar页面reLaunch可以打开任意页面- 页面底部的
tabBar由页面决定,即只要是定义为tabBar的页面,底部都有tabBar - 不能在
App.vue里面进行页面跳转
$getAppWebview()
uni-app 在 内置了一个方法 $getAppWebview() :得到当前webview的对象实例
此方法仅 App 支持
js
var pages = getCurrentPages();
var page = pages[pages.length - 1];
// #ifdef APP-PLUS
var currentWebview = page.$getAppWebview();
console.log(currentWebview.id);//获得当前webview的id
console.log(currentWebview.isVisible());//查询当前webview是否可见
);
// #endif页面通讯
uni.$emit(eventName,OBJECT)
触发全局的自定事件。附加参数都会传给监听器回调。
| 属性 | 类型 | 描述 |
|---|---|---|
eventName | String | 事件名 |
OBJECT | Object | 触发事件携带的附加参数 |
uni.$on(eventName,callback)
监听全局的自定义事件。事件由 uni.$emit 触发,回调函数会接收所有传入事件触发函数的额外参数。
| 属性 | 类型 | 描述 |
|---|---|---|
eventName | String | 事件名 |
callback | Function | 事件的回调函数 |
uni.$once(eventName,callback)
监听全局的自定义事件。但只触发一次,触发后移除监听器。
| 属性 | 类型 | 描述 |
|---|---|---|
eventName | String | 事件名 |
callback | Function | 事件的回调函数 |
uni.$off(eventName, callback])
移除全局自定义事件监听器
| 属性 | 类型 | 描述 |
|---|---|---|
eventName | Array < String > | 事件名 |
callback | Function | 事件的回调函数 |
Tips
- 无参数:移除所有事件监听器
- 只提供事件:移除该事件所有的监听器
- 同时提供事件与回调:只移除此回调的监听器,提供回调必须跟
$on回调为同一个才能移除
上述函数触发的事件都是 App 全局级别的,跨任意组件,页面,nvue,vue 等
onLoad里边uni.$on注册监听onUnload里边uni.$off移除- 一次性事件,直接使用
uni.$once监听