生成uni-app模版
- 点击HBuilder左上角图标选择项目
- 填写项目信息,选择项目模版
uni-app项目构成
uni-app目录构成
.hbuilderx文件中的launch.json文件配置了启动调试时相关设置pages文件用来存放页面。static是一个存放静态资源的文件夹,例如图片等。App.vue是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素。index.html是一个渲染页面。main.js是uni-app的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如vuex。manifest.json文件是应用的配置文件,用于指定应用的名称、图标、权限等。HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录。pages.json文件用来对uni-app进行全局配置的,决定页面的路径、窗口样式,原生导航栏、底部tab栏等。uni.scss文件的用途是为了方便整体控制应用的风格。
uni-app页面生命周期
| 函数名 | 说明 | 平台差异说明 | 最低版本 |
|---|---|---|---|
| onInit | 监听页面初始化,其参数同 onLoad 参数,为上个页面传递的数据,参数类型为 Object(用于页面传参),触发时机早于 onLoad | 百度小程序 | 3.1.0+ |
| onLoad | 监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例 | ||
| onShow | 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 | ||
| onReady | 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发 | ||
| onHide | 监听页面隐藏 | ||
| onUnload | 监听页面卸载 | ||
| onResize | 监听窗口尺寸变化 | App、微信小程序 | |
| onPullDownRefresh | 监听用户下拉动作,一般用于下拉刷新,参考示例 | ||
| onReachBottom | 页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。具体见下方注意事项 | ||
| onTabItemTap | 点击 tab 时触发,参数为Object,具体见下方注意事项 | 微信小程序、QQ小程序、支付宝小程序、百度小程序、H5、App | |
| onShareAppMessage | 用户点击右上角分享 | 微信小程序、QQ小程序、支付宝小程序、字节小程序、飞书小程序、快手小程序 | |
| onPageScroll | 监听页面滚动,参数为Object | nvue暂不支持 | |
| onNavigationBarButtonTap | 监听原生标题栏按钮点击事件,参数为Object | App、H5 | |
| onBackPress | 监听页面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack ;详细说明及使用:onBackPress 详解。支付宝小程序只有真机能触发,只能监听非navigateBack引起的返回,不可阻止默认行为。 | app、H5、支付宝小程序 | |
| onNavigationBarSearchInputChanged | 监听原生标题栏搜索输入框输入内容变化事件 | App、H5 | 1.6.0 |
| onNavigationBarSearchInputConfirmed | 监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。 | App、H5 | 1.6.0 |
| onNavigationBarSearchInputClicked | 监听原生标题栏搜索输入框点击事件(pages.json 中的 searchInput 配置 disabled 为 true 时才会触发) | App、H5 | 1.6.0 |
| onShareTimeline | 监听用户点击右上角转发到朋友圈 | 微信小程序 | 2.8.1+ |
| onAddToFavorites | 监听用户点击右上角收藏 | 微信小程序 | 2.8.1+ |
onInit使用注意
- 仅百度小程序基础库 3.260 以上支持 onInit 生命周期
- 其他版本或平台可以同时使用 onLoad 生命周期进行兼容,注意避免重复执行相同逻辑
- 不依赖页面传参的逻辑可以直接使用 created 生命周期替代
onReachBottom使用注意 可在pages.json里定义具体页面底部的触发距离onReachBottomDistance,比如设为50,那么滚动页面到距离底部50px时,就会触发onReachBottom事件。
如使用scroll-view导致页面没有滚动,则触底事件不会被触发。scroll-view滚动到底部的事件请参考scroll-view的文档
onPageScroll (监听滚动、滚动监听、滚动事件)参数说明:
| 属性 | 类型 | 说明 |
|---|---|---|
| scrollTop | Number | 页面在垂直方向已滚动的距离(单位px) |
注意
onPageScroll里不要写交互复杂的js,比如频繁修改页面。因为这个生命周期是在渲染层触发的,在非h5端,js是在逻辑层执行的,两层之间通信是有损耗的。如果在滚动过程中,频发触发两层之间的数据交换,可能会造成卡顿。- 如果想实现滚动时标题栏透明渐变,在App和H5下,可在pages.json中配置titleNView下的type为transparent,参考。
- 如果需要滚动吸顶固定某些元素,推荐使用css的粘性布局,参考插件市场。插件市场也有其他js实现的吸顶插件,但性能不佳,需要时可自行搜索。
- 在App、微信小程序、H5中,也可以使用wxs监听滚动,参考;在app-nvue中,可以使用bindingx监听滚动,参考。
onBackPress上不可使用async,会导致无法阻止默认返回
onPageScroll : function(e) { //nvue暂不支持滚动监听,可用bindingx代替
console.log("滚动距离为:" + e.scrollTop);
},
onTabItemTap 返回的json对象说明:
| 属性 | 类型 | 说明 |
|---|---|---|
| index | String | 被点击tabItem的序号,从0开始 |
| pagePath | String | 被点击tabItem的页面路径 |
| text | String | 被点击tabItem的按钮文字 |
注意
- onTabItemTap常用于点击当前tabitem,滚动或刷新当前页面。如果是点击不同的tabitem,一定会触发页面切换。
- 如果想在App端实现点击某个tabitem不跳转页面,不能使用onTabItemTap,可以使用plus.nativeObj.view放一个区块盖住原先的tabitem,并拦截点击事件。
- 支付宝小程序平台onTabItemTap表现为点击非当前tabitem后触发,因此不能用于实现点击返回顶部这种操作
onTabItemTap : function(e) {
console.log(e);
// e的返回格式为json对象: {"index":0,"text":"首页","pagePath":"pages/index/index"}
},
onNavigationBarButtonTap 参数说明:
| 属性 | 类型 | 说明 |
|---|---|---|
| index | Number | 原生标题栏按钮数组的下标 |
onNavigationBarButtonTap : function (e) {
console.log(e);
// e的返回格式为json对象:{"text":"测试","index":0}
}
onBackPress 回调参数对象说明:
| 属性 | 类型 | 说明 |
|---|---|---|
| from | String | 触发返回行为的来源:'backbutton'——左上角导航栏按钮及安卓返回键;'navigateBack'——uni.navigateBack() 方法。支付宝小程序端不支持返回此字段 |
export default {
data() {
return {};
},
onBackPress(options) {
console.log('from:' + options.from)
}
}
注意
- nvue 页面weex编译模式支持的生命周期同weex,具体参考:weex生命周期介绍。
- 支付宝小程序真机可以监听到非
navigateBack引发的返回事件(使用小程序开发工具时不会触发onBackPress),不可以阻止默认返回行为
组件生命周期
| 标题 | 说明 | 平台差异说明 | 最低版本 |
|---|---|---|---|
| beforeCreate | 在实例初始化之后被调用。详见 | ||
| created | 在实例创建完成后被立即调用。详见 | ||
| beforeMount | 在挂载开始之前被调用。详见 | ||
| mounted | 挂载到实例上去之后调用。详见 注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTickVue官方文档 | ||
| beforeUpdate | 数据更新时调用,发生在虚拟 DOM 打补丁之前。详见 | 仅H5平台支持 | |
| updated | 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。详见 | 仅H5平台支持 | |
| beforeDestroy | 实例销毁之前调用。在这一步,实例仍然完全可用。详见 | ||
| destroyed | Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。详见 |
uni-app的配置文件
pages.json
pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等。
它类似微信小程序中app.json的页面管理部分。注意定位权限申请等原属于app.json的内容,在uni-app中是在manifest中配置。
配置项列表
| 属性 | 类型 | 必填 | 描述 | 平台兼容 |
|---|---|---|---|---|
| globalStyle | Object | 否 | 设置默认页面的窗口表现 | |
| pages | Object Array | 是 | 设置页面路径及窗口表现 | |
| easycom | Object | 否 | 组件自动引入规则 | 2.5.5+ |
| tabBar | Object | 否 | 设置底部 tab 的表现 | |
| condition | Object | 否 | 启动模式配置 | |
| subPackages | Object Array | 否 | 分包加载配置 | |
| preloadRule | Object | 否 | 分包预下载规则 | 微信小程序 |
| workers | String | 否 | Worker 代码放置的目录 | 微信小程序 |
| leftWindow | Object | 否 | 大屏左侧窗口 | H5 |
| topWindow | Object | 否 | 大屏顶部窗口 | H5 |
| rightWindow | Object | 否 | 大屏右侧窗口 | H5 |
以下是一个包含了所有配置选项的 pages.json :
"pages": [{
"path": "pages/component/index",
"style": {
"navigationBarTitleText": "组件"
}
}, {
"path": "pages/API/index",
"style": {
"navigationBarTitleText": "接口"
}
}, {
"path": "pages/component/view/index",
"style": {
"navigationBarTitleText": "view"
}
}],
"condition": { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [{
"name": "test", //模式名称
"path": "pages/component/view/index" //启动页面,必选
}]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "演示",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"usingComponents":{
"collapse-tree-item":"/components/collapse-tree-item"
},
"renderingMode": "seperated", // 仅微信小程序,webrtc 无法正常时尝试强制关闭同层渲染
"pageOrientation": "portrait", //横屏配置,全局屏幕旋转设置(仅 APP/微信/QQ小程序),支持 auto / portrait / landscape
"rpxCalcMaxDeviceWidth": 960,
"rpxCalcBaseDeviceWidth": 375,
"rpxCalcIncludeWidth": 750
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"height": "50px",
"fontSize": "10px",
"iconWidth": "24px",
"spacing": "3px",
"list": [{
"pagePath": "pages/component/index",
"iconPath": "static/image/icon_component.png",
"selectedIconPath": "static/image/icon_component_HL.png",
"text": "组件"
}, {
"pagePath": "pages/API/index",
"iconPath": "static/image/icon_API.png",
"selectedIconPath": "static/image/icon_API_HL.png",
"text": "接口"
}],
"midButton": {
"width": "80px",
"height": "50px",
"text": "文字",
"iconPath": "static/image/midButton_iconPath.png",
"iconWidth": "24px",
"backgroundImage": "static/image/midButton_backgroundImage.png"
}
},
"easycom": {
"autoscan": true, //是否自动扫描组件
"custom": {//自定义扫描规则
"^uni-(.*)": "@/components/uni-$1.vue"
}
},
"topWindow": {
"path": "responsive/top-window.vue",
"style": {
"height": "44px"
}
},
"leftWindow": {
"path": "responsive/left-window.vue",
"style": {
"width": "300px"
}
},
"rightWindow": {
"path": "responsive/right-window.vue",
"style": {
"width": "300px"
},
"matchMedia": {
"minWidth": 768
}
}
}
关于分包优化的说明
-
在对应平台的配置下添加
"optimization":{"subPackages":true}开启分包优化 -
目前只支持
mp-weixin、mp-qq、mp-baidu、mp-toutiao的分包优化 -
分包优化具体逻辑:
- 静态文件:分包下支持 static 等静态资源拷贝,即分包目录内放置的静态资源不会被打包到主包中,也不可在主包中使用
- js文件:当某个 js 仅被一个分包引用时,该 js 会被打包到该分包内,否则仍打到主包(即被主包引用,或被超过 1 个分包引用)
- 自定义组件:若某个自定义组件仅被一个分包引用时,且未放入到分包内,编译时会输出提示信息
"subPackages": [{ "root": "pages/sub", "pages": [{ "path": "index/index" }] }]
manifest.json
manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录。
配置项列表
| 属性 | 类型 | 默认值 | 描述 | 最低版本 |
|---|---|---|---|---|
| name | String | 应用名称 | ||
| appid | String | 新建 uni-app 项目时,DCloud 云端分配。用途详见 | 应用标识 | |
| description | String | 应用描述 | ||
| locale | String | auto | 设置当前默认语言,具体参考 locale | |
| versionName | String | 版本名称,例如:1.0.0。详见下方Tips说明 | ||
| versionCode | String | 版本号,例如:36 | ||
| transformPx | Boolean | true | 是否转换项目的px,为true时将px转换为rpx,为false时,px为传统的实际像素 | |
| networkTimeout | Object | 网络超时时间,详见 | ||
| debug | Boolean | false | 是否开启 debug 模式,开启后调试信息以 info 的形式给出,其信息有页面的注册,页面路由,数据更新,事件触发等 | |
| uniStatistics | Object | 是否开启 uni 统计,全局配置 | 2.2.3+ | |
| app-plus | Object | App 特有配置 | ||
| h5 | Object | H5 特有配置 | ||
| quickapp | Object | 快应用特有配置,即将支持 | ||
| mp-weixin | Object | 微信小程序特有配置 | ||
| mp-alipay | Object | 支付宝小程序特有配置 | ||
| mp-baidu | Object | 百度小程序特有配置 | ||
| mp-toutiao | Object | 字节跳动小程序特有配置 | 1.6.0 | |
| mp-lark | Object | 飞书小程序特有配置 | 3.2.12 | |
| mp-qq | Object | qq 小程序特有配置 | 2.1.0 |
完整 manifest.json
{
"appid": "__UNI__XXXXXX,创建应用时云端分配的,不要修改。",
"name": "应用名称,如uni-app",
"description": "应用描述",
"versionName": "1.0.0",
"versionCode": "100",
"uniStatistics": {
"enable": false
},
"app-plus": {
"screenOrientation": [
"portrait-primary",
"landscape-primary",
"portrait-secondary",
"landscape-secondary"
],
"optimization": {
"subPackages": true
},
"modules": {
"Contacts": {},
"Fingerprint": {},
"Maps": {},
"Messaging": {},
"OAuth": {},
"Payment": {},
"Push": {},
"Share": {},
"Speech": {},
"Statistic": {},
"VideoPlayer": {},
"LivePusher": {}
},
"distribute": {
"android": {
"packagename": "Android应用包名,如io.dcloud.uniapp",
"keystore": "Android应用打包使用的密钥库文件",
"password": "Android应用打包使用密钥库中证书的密码",
"aliasname": "Android应用打包使用密钥库中证书的别名",
"schemes": [
"应用支持的scheme,大小写相关,推荐使用小写"
],
"theme": "程序使用的主题",
"android:name": "自定义程序入口类名",
"custompermissions": "Boolean类型,是否自定义android权限,true表示自定义权限,只使用permissions下指定的android权限,不根据用户使用的5+模块自动添加android权限,false表示自动根据用户使用的5+模块自动添加android权限",
"permissions": [
"要添加的额外的android权限,如<uses-permission android:name=\"com.android.launcher.permission.INSTALL_SHORTCUT\" />",
"<uses-permission android:name=\"com.android.launcher.permission.UNINSTALL_SHORTCUT\" />"
],
"minSdkVersion": "apk支持的最低版本,默认值为14",
"targetSdkVersion": "apk的目标版本,默认值为21"
},
"ios": {
"appid": "iOS应用标识,苹果开发网站申请的appid,如io.dcloud.uniapp",
"mobileprovision": "iOS应用打包配置文件",
"password": "iOS应用打包个人证书导入密码",
"p12": "iOS应用打包个人证书,打包配置文件关联的个人证书",
"devices": "iOS应用支持的设备类型,可取值iphone/ipad/universal",
"urltypes": [
{
"urlidentifier": "com.xxx.test",
"urlschemes": [
"hbuilder"
]
}
],
"frameworks": [
"使用native.js调用API要引用的库文件名称,如CoreLocation.framework",
"QuartzCore.framework"
],
"idfa": "true|false,是否使用广告标识符,默认值为false",
"plistcmds": [
"Set :权限 使用权限的原因",
"Set :NSCameraUsageDescription 说明使用用户相机的原因"
]
},
"sdkConfigs": {
"maps": {
"baidu": {
"appkey_ios": "",
"appkey_android": ""
}
},
"oauth": {
"weixin": {
"appid": "",
"appsecret": ""
},
"qq": {
"appid": ""
},
"sina": {
"appkey": "",
"appsecret": "",
"redirect_uri": ""
},
"xiaomi": {
"appid_ios": "",
"appsecret_ios": "",
"redirect_uri_ios": "",
"appid_android": "",
"appsecret_android": "",
"redirect_uri_android": ""
}
},
"payment": {
"appleiap": {},
"alipay": {
"scheme": ""
},
"weixin": {
"appid": ""
}
},
"push": {
"igexin": {
"appid": "",
"appkey": "",
"appsecret": ""
}
},
"share": {
"weixin": {
"appid": ""
},
"sina": {
"appkey": "",
"appsecret": "",
"redirect_uri": ""
},
"qq": {
"appid": ""
}
},
"statics": {
"umeng": {
"appkey_ios": "",
"channelid_ios": "",
"appkey_android": "",
"channelid_android": ""
}
}
},
"icons": {
"ios": {
"appstore": "必选, 1024x1024, 提交app sotre使用的图标",
"iphone": {
"app@2x": "可选,120x120,iOS7-11程序图标(iPhone4S/5/6/7/8)",
"app@3x": "可选,180x180,iOS7-11程序图标(iPhone6plus/7plus/8plus/X)",
"spotlight@2x": "可选,80x80,iOS7-11 Spotlight搜索图标(iPhone5/6/7/8)",
"spotlight@3x": "可选,120x120,iOS7-11 Spotlight搜索图标(iPhone6plus/7plus/8plus/X)",
"settings@2x": "可选,58x58,iOS5-11 Settings设置图标(iPhone5/6/7/8)",
"settings@3x": "可选,87x87,iOS5-11 Settings设置图标(iPhone6plus/7plus/8plus/X)",
"notification@2x": "可选,40x40,iOS7-11 通知栏图标(iPhone5/6/7/8)",
"notification@3x": "可选,60x60,iOS7-11 通知栏图标(iPhone6plus/7plus/8plus/X)"
},
"ipad": {
"app": "可选,76x76,iOS7-11程序图标",
"app@2x": "可选,152x152,iOS7-11程序图标(高分屏)",
"proapp@2x": "可选,167x167,iOS9-11程序图标(iPad Pro)",
"spotlight": "可选,40x40,iOS7-11 Spotlight搜索图标",
"spotlight@2x": "可选,80x80,iOS7-11 Spotlight搜索图标(高分屏)",
"settings": "可选,29x29,iOS5-11 设置图标",
"settings@2x": "可选,58x58,iOS5-11 设置图标(高分屏)",
"notification": "可选,20x20,iOS7-11 通知栏图标",
"notification@2x": "可选,40x40,iOS7-11 通知栏图标(高分屏)"
}
},
"android": {
"mdpi": "必选,48x48,普通屏程序图标",
"ldpi": "必选,48x48,大屏程序图标",
"hdpi": "必选,72x72,高分屏程序图标",
"xhdpi": "必选,96x96,720P高分屏程序图标",
"xxhdpi": "必选,144x144,1080P高分屏程序图标",
"xxxhdpi": "可选,192x192"
}
},
"splashscreen": {
"ios": {
"iphone": {
"retina35": "可选,640x960,3.5英寸设备(iPhone4)启动图片",
"retina40": "可选,640x1136,4.0英寸设备(iPhone5)启动图片",
"retina40l": "可选,1136x640,4.0英寸设备(iPhone5)横屏启动图片",
"retina47": "可选,750x1334,4.7英寸设备(iPhone6)启动图片",
"retina47l": "可选,1334x750,4.7英寸设备(iPhone6)横屏启动图片",
"retina55": "可选,1242x2208,5.5英寸设备(iPhone6Plus)启动图片",
"retina55l": "可选,2208x1242,5.5英寸设备(iPhone6Plus)横屏启动图片",
"iphonex": "可选,1125x2436,iPhoneX启动图片",
"iphonexl": "可选,2436x1125,iPhoneX横屏启动图片"
},
"ipad": {
"portrait": "可选,768x1004,需支持iPad时必选,iPad竖屏启动图片",
"portrait-retina": "可选,1536x2008,需支持iPad时必选,iPad高分屏竖屏图片",
"landscape": "可选,1024x748,需支持iPad时必选,iPad横屏启动图片",
"landscape-retina": "可选,2048x1496,需支持iPad时必选,iPad高分屏横屏启动图片",
"portrait7": "可选,768x1024,需支持iPad iOS7时必选,iPad竖屏启动图片",
"portrait-retina7": "可选,1536x2048,需支持iPad iOS7时必选,iPad高分屏竖屏图片",
"landscape7": "可选,1024x768,需支持iPad iOS7时必选,iPad横屏启动图片",
"landscape-retina7": "可选,2048x1536,需支持iPad iOS7时必选,iPad高分屏横屏启动图片"
}
},
"android": {
"mdpi": "必选,240x282,普通屏启动图片",
"ldpi": "必选,320x442,大屏启动图片",
"hdpi": "必选,480x762,高分屏启动图片",
"xhdpi": "必选,720x1242,720P高分屏启动图片",
"xxhdpi": "必选,1080x1882,1080P高分屏启动图片"
}
}
},
"splashscreen": {
"waiting": true,
"autoclose": true
},
"error": {
"url": "页面加载错误时打开的页面地址,可以是网络地址,也可以是本地地址"
},
"useragent": {
"value": "自定义ua字符串",
"concatenate": "是否为追加模式"
},
"useragent_ios": {
"value": "与useragent的value一致,仅在iOS平台生效,当useragent和useragent_ios同时存在时优先级useragent_ios>useragent",
"concatenate": "与useragent的concatenate一致,仅iOS平台生效"
},
"useragent_android": {
"value": "与useragent的value一致,仅在Android平台生效,当useragent和useragent_android同时存在时优先级useragent_android>useragent",
"concatenate": "与useragent的concatenate一致,仅Android平台生效"
},
"ssl": "accept|refuse|warning,访问https网络时对非受信证书的处理逻辑",
"runmode": "normal",
"appWhitelist": [
"Android平台下载apk地址白名单列表",
"iOS平台跳转appstore地址白名单列表"
],
"schemeWhitelist": [
"URL Scheme白名单列表,如:mqq"
],
"channel": "渠道标记,可在DCloud开发者中心查看各渠道应用的统计数据",
"adid": "广告联盟会员id,在DCloud开发者中心申请后填写",
"safearea": {
"background": "#CCCCCC",
"bottom": {
"offset": "none|auto"
},
"left": {
"offset": "none|auto"
},
"right": {
"offset": "none|auto"
}
},
"softinput": {
"navBar": "auto",
"mode": "adjustResize|adjustPan"
},
"popGesture": "none"
},
"quickapp": {},
"mp-weixin": {
"appid": "wx开头的微信小程序appid",
"uniStatistics": {
"enable": false
}
},
"mp-baidu": {
"appid": "百度小程序appid"
},
"mp-toutiao": {
"appid": "字节跳动小程序appid"
},
"mp-lark": {
"appid": "飞书小程序appid"
},
"h5": {
"title": "演示",
"template": "index.html",
"router": {
"mode": "history",
"base": "/hello/"
},
"async": {
"loading": "AsyncLoading",
"error": "AsyncError",
"delay": 200,
"timeout": 3000
}
}
}
package.json
- 在开发web时,有时需要一套代码编译发布到不同的站点,比如主站和微信h5站。(注意不是一套代码内部自适应不同浏览器,是真的分离部署了不同的网站)
- 在开发小程序时,经常有扩展小程序平台,比如基于阿里小程序的钉钉小程序、淘宝小程序。
uni-app 通过在package.json文件中增加uni-app扩展节点,可实现自定义条件编译平台。
扩展新的平台后,有3点影响:
- 可以在代码里编写自定义的条件编译,为这个新平台编写专用代码
- 运行时可以执行面向新平台的编译运行
- 发行时可以执行面向新平台的编译发行
注意只能扩展web和小程序平台,不能扩展app打包。并且扩展小程序平台时只能基于指定的基准平台扩展子平台,不能扩展基准平台。基准平台详见下文。
package.json扩展配置用法:
/**
* package.json其它原有配置
* 拷贝代码后请去掉注释!
*/
"uni-app": {// 扩展配置
"scripts": {
"custom-platform": { //自定义编译平台配置,可通过cli方式调用
"title":"自定义扩展名称", // 在HBuilderX中会显示在 运行/发行 菜单中
"browser":"", //运行到的目标浏览器,仅当UNI_PLATFORM为h5时有效
"env": {//环境变量
"UNI_PLATFORM": "", //基准平台
"MY_TEST": "", // ... 其他自定义环境变量
},
"define": { //自定义条件编译
"CUSTOM-CONST": true //自定义条件编译常量,建议为大写
}
}
}
}
}
Tips:
UNI_PLATFORM仅支持填写uni-app默认支持的基准平台,目前仅限如下枚举值:h5、mp-weixin、mp-alipay、mp-baidu、mp-toutiao、mp-qqbrowser仅在UNI_PLATFORM为h5时有效,目前仅限如下枚举值:chrome、firefox、id、edge、safari、hbuilderxpackage.json文件中不允许出现注释,否则扩展配置无效vue-cli需更新到最新版,HBuilderX需升级到 2.1.6+ 版本
vue.config.js
uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量预置。
支持情况
- CLI 工程
- HBuilderX 2.1.5 及以上版本
注意事项
- 仅vue页面生效
部分配置项会被编译配置覆盖,例如:
- publicPath 不支持,如果需要配置,请在 manifest.json->h5->router->base 中配置,参考文档:h5-router
- outputDir 不支持
- assetsDir 固定 static
- pages 不支持
- runtimeCompiler 固定 false
- productionSourceMap 固定 false
- css.extract H5 平台固定 false,其他平台固定 true
- parallel 固定 false
- 使用cli项目时,默认情况下 babel-loader 会忽略所有 node_modules 中的文件。如果你想要通过 Babel 显式转译一个依赖,可以在transpileDependencies中列出来。详情参考 使用示例
自定义静态资源目录
const CopyWebpackPlugin = require('copy-webpack-plugin') //最新版本copy-webpack-plugin插件暂不兼容,推荐v5.0.0
module.exports = {
configureWebpack: {
plugins: [
new CopyWebpackPlugin([
{
from: path.join(__dirname, 'src/images'),
to: path.join(__dirname, 'dist', process.env.NODE_ENV === 'production' ? 'build' : 'dev', process.env.UNI_PLATFORM, 'images')
}
])
]
}
}
注入全局依赖
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
'localStorage': ['mp-storage', 'localStorage'],
'window.localStorage': ['mp-storage', 'localStorage']
})
]
}
}
配置环境变量
module.exports = {
chainWebpack: config => {
config
.plugin('define')
.tap(args => {
args[0]['process.env'].VUE_APP_TEST = '"test"'
return args
})
}
}
启用压缩的方法:
- HBuilderX创建的项目勾选运行-->运行到小程序模拟器-->运行时是否压缩代码
- cli创建的项目可以在
package.json中添加参数--minimize,示例:"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize"
uni.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策略。
注意:
-
如要使用这些常用变量,需要在 HBuilderX 里面安装 scss 插件;
-
使用时需要在 style 节点上加上
lang="scss"。<style lang="scss"> </style> -
pages.json不支持scss,原生导航栏和tabbar的动态修改只能使用js api 以下是 uni.scss 的相关变量:
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:24rpx;
$uni-font-size-base:28rpx;
$uni-font-size-lg:32rpx;
/* 图片尺寸 */
$uni-img-size-sm:40rpx;
$uni-img-size-base:52rpx;
$uni-img-size-lg:80rpx;
/* Border Radius */
$uni-border-radius-sm: 4rpx;
$uni-border-radius-base: 6rpx;
$uni-border-radius-lg: 12rpx;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 10px;
$uni-spacing-row-base: 20rpx;
$uni-spacing-row-lg: 30rpx;
/* 垂直间距 */
$uni-spacing-col-sm: 8rpx;
$uni-spacing-col-base: 16rpx;
$uni-spacing-col-lg: 24rpx;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:40rpx;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:36rpx;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:30rpx;
App.vue
应用生命周期
| 函数名 | 说明 |
|---|---|
| onLaunch | 当uni-app 初始化完成时触发(全局只触发一次) |
| onShow | 当 uni-app 启动,或从后台进入前台显示 |
| onHide | 当 uni-app 从前台进入后台 |
| onError | 当 uni-app 报错时触发 |
| onUniNViewMessage | 对 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯 |
| onUnhandledRejection | 对未处理的 Promise 拒绝事件监听函数(2.8.1+) |
| onPageNotFound | 页面不存在监听函数 |
| onThemeChange | 监听系统主题变化 |
| 注意 |
- 应用生命周期仅可在
App.vue中监听,在其它页面监听无效。 - onlaunch里进行页面跳转,如遇白屏报错,请参考ask.dcloud.net.cn/article/359…
- onPageNotFound 页面实际上已经打开了(比如通过分享卡片、小程序码)且发现页面不存在,才会触发,api 跳转不存在的页面不会触发(如 uni.navigateTo)
// 只能在App.vue里监听应用的生命周期
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
globalData
小程序有globalData,这是一种简单的全局变量机制。这套机制在uni-app里也可以使用,并且全端通用。
以下是 App.vue 中定义globalData的相关配置:
export default {
globalData: {
text: 'text'
}
}
</script>
全局样式
在App.vue中,可以定义一些全局通用样式,例如需要加一个通用的背景色,首屏页面渲染的动画等都可以写在App.vue中。
注意如果工程下同时有vue和nvue文件,全局样式的所有css会应用于所有文件,而nvue支持的css有限,编译器会在控制台报警,提示某些css无法在nvue中支持。此时需要把nvue不支持的css写在单独的条件编译里。如:
/* #ifndef APP-PLUS-NVUE */
@import './common/uni.css';
/* #endif*/
</style>
main.js
main.js是uni-app的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如vuex。
首先引入了Vue库和App.vue,创建了一个vue实例,并且挂载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中进行配置。如果开发者坚持使用vue-router,可以在插件市场找到转换插件。
注意
- nvue 暂不支持在 main.js 注册全局组件
Uni-app开发与小程序开发有什么区别
在建设。。。
宿主环境
在建设。。。
Uni-app的组件
在建设。。。
Uni-app的api
在建设。。。