提交 ff93f8e4 编写于 作者: D DCloud_LXH

Merge branch 'master' into vuepress

......@@ -113,7 +113,7 @@ uni.request({
console.error(err)
})
// 使用 Await/Await 方式调用
// 使用 Async/Await 方式调用
async function request () {
try{
var res = await uni.request({
......
......@@ -872,5 +872,5 @@ code|message|
- App平台,建议每个广告商每个设备每天调用次数不超过`15`,中间要有间隔时间,否则可能触发系统的反作弊策略导致流量收益下降。
### 案例参考
- [全民董事长](https://android.myapp.com/myapp/detail.htm?apkName=com.dlt.qmdsz&info=DF3F955B42F0B77FECA41F03E7F77C8D)
- 重要项目源码《养猫合成游戏》,拿走就能用,[https://ext.dcloud.net.cn/plugin?id=4095](https://ext.dcloud.net.cn/plugin?id=4095)
- 项目源码《养猫合成游戏》,拿走就能用,[https://ext.dcloud.net.cn/plugin?id=4095](https://ext.dcloud.net.cn/plugin?id=4095)
- 项目源码《有奖猜歌》,拿走就能用,[https://ext.dcloud.net.cn/plugin?id=4826](https://ext.dcloud.net.cn/plugin?id=4826)
......@@ -90,14 +90,14 @@ uni.getLocation({
**OBJECT 参数说明**
|参数名|类型|必填|说明|
|:-|:-|:-|:-|
|latitude|Number|否|目标地纬度,仅微信小程序2.9.0+支持|
|longitude|Number|否|目标地经度,仅微信小程序2.9.0+支持|
|keyword|String|否|搜索关键字,仅App平台支持|
|success|Function|是|接口调用成功的回调函数,返回内容详见返回参数说明。|
|fail|Function|否|接口调用失败的回调函数(获取定位失败、用户取消等情况下触发)|
|complete|Function|否|接口调用结束的回调函数(调用成功、失败都会执行)|
|参数名|类型|必填|说明|平台差异说明|
|:-|:-|:-|:-|:-|
|latitude|Number|否|目标地纬度|微信小程序(2.9.0+)、H5-Vue3(3.2.10+)|
|longitude|Number|否|目标地经度|微信小程序(2.9.0+)、H5-Vue3(3.2.10+)|
|keyword|String|否|搜索关键字,仅App平台支持||
|success|Function|是|接口调用成功的回调函数,返回内容详见返回参数说明。||
|fail|Function|否|接口调用失败的回调函数(获取定位失败、用户取消等情况下触发)||
|complete|Function|否|接口调用结束的回调函数(调用成功、失败都会执行)||
**注意**
- 因平台差异,如果SDK配置百度地图,需要设置keyword,才能显示相关地点
......
......@@ -59,7 +59,7 @@ uni.navigateTo({
},
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'data from starter page' })
res.eventChannel.emit('acceptDataFromOpenedPage', { data: 'data from starter page' })
}
})
......@@ -208,6 +208,9 @@ uni.switchTab({
|delta|Number|否|1|返回的页面数,如果 delta 大于现有页面数,则返回到首页。||
|animationType|String|否|pop-out|窗口关闭的动画效果,详见:[窗口动画](api/router?id=animation)|App|
|animationDuration|Number|否|300|窗口关闭动画的持续时间,单位为 ms|App|
|success|Function|否|接口调用成功的回调函数|
|fail|Function|否|接口调用失败的回调函数|
|complete|Function|否|接口调用结束的回调函数(调用成功、失败都会执行)|
**示例**
......
......@@ -32,10 +32,20 @@
|serviceId|string||是|蓝牙特征值对应服务的 uuid|
|characteristicId|string||是|蓝牙特征值的 uuid|
|value|ArrayBuffer||是|蓝牙设备特征值对应的二进制值|
|writeType|string||是|蓝牙特征值的写模式设置,有两种模式,iOS 优先 write,安卓优先 writeNoResponse 。微信小程序支持|
|success|function||否|接口调用成功的回调函数|
|fail|function||否|接口调用失败的回调函数|
|complete|function||否|接口调用结束的回调函数(调用成功、失败都会执行)|
**writeType**
|属性|说明|
|:-|:-|
|write|强制回复写,不支持时报错|
|writeNoResponse|强制无回复写,不支持时报错|
#### 错误
|错误码|错误信息|说明|
......
......@@ -2,7 +2,7 @@
|App|H5|微信小程序|支付宝小程序|百度小程序|字节跳动小程序、飞书小程序|QQ小程序|快手小程序|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|√|x|√|√|√|√|√|√|
|√||√|√|√|√|√|√|
### uni.setClipboardData(OBJECT)
设置系统剪贴板的内容。
......@@ -56,5 +56,4 @@ uni.getClipboardData({
#### **注意**
- 设置剪贴板内容后,小程序平台会自动弹出轻提示。App平台默认与小程序保持一致策略。如不希望在App平台弹出提示,可使用Native.js自行操作剪贴板,插件市场有封装好的示例[https://ext.dcloud.net.cn/plugin?id=712](https://ext.dcloud.net.cn/plugin?id=712)。也可以在设置剪切板后立即uni.hideToast()。
- H5的复制粘贴,可去插件市场搜索[剪贴板](https://ext.dcloud.net.cn/search?q=%E5%89%AA%E8%B4%B4%E6%9D%BF)
- 设置剪贴板内容后,小程序平台会自动弹出轻提示。App平台默认与小程序保持一致策略。如不希望在App平台弹出提示,可使用Native.js自行操作剪贴板,插件市场有封装好的示例[https://ext.dcloud.net.cn/plugin?id=712](https://ext.dcloud.net.cn/plugin?id=712)。也可以在设置剪切板后立即uni.hideToast()。
\ No newline at end of file
......@@ -20,8 +20,10 @@
|值|说明|平台差异说明|
|:-|:-|:-|
|success|显示成功图标,此时 title 文本在`小程序`平台最多显示 7 个汉字长度。||
|error|显示错误图标,此时 title 文本在`小程序`平台最多显示 7 个汉字长度。||
|success|显示成功图标,此时 title 文本在`小程序`平台最多显示 7 个汉字长度。|支付宝小程序无长度无限制|
|error|显示错误图标,此时 title 文本在`小程序`平台最多显示 7 个汉字长度。|支付宝小程序不支持|
|fail|显示错误图标,此时 title 文本无长度显示。|支付宝小程序|
|exception|显示异常图标。此时 title 文本无长度显示。|支付宝小程序|
|loading|显示加载图标,此时 title 文本在`小程序`平台最多显示 7 个汉字长度。|支付宝小程序不支持|
|none|不显示图标,此时 title 文本在`小程序`最多可显示两行,`App`仅支持单行显示。| |
......
......@@ -3,6 +3,7 @@
目前需分平台编写
- 微信小程序:[规范详情](https://developers.weixin.qq.com/miniprogram/dev/api/worker/wx.createWorker.html)
- 支付宝小程序:[规范详情](https://opendocs.alipay.com/mini/api/worker)
- 字节跳动小程序:[规范详情](https://microapp.bytedance.com/docs/zh-CN/mini-game/develop/api/worker/tt-create-worker)
- QQ小程序:[规范详情](https://q.qq.com/wiki/develop/miniprogram/API/worker/worker.html)
- H5:标准H5的worker仍然可以使用
......
App的安装包都可以解压。前端资源,一般都是明文存放在安装包中,为防止解压后泄露敏感信息,需要进行安全处理。
由此DCloud提供了App端的js/nvue文件的原生混淆。5+ App/Wap2App支持对指定的js进行原生混淆。uni-app支持对指定的nvue文件原生混淆。
原生混淆后的安装包,解压后看到的都是乱码。
但需要注意:
1. 没有绝对的安全,非常重要的信息,应该保存在服务器而不是前端
2. 运行期对资源代码解密是影响执行性能的。不建议全包混淆,仅挑选需要保护的个别文件处理即可
3. uni-app项目制作wgt包不支持原生混淆加密(即使配置也不会生效),HBuilderX3.1.0+版本后支持
4. 为了保证加密数据的安全性,加密算法和key不对外公开,因此离线打包无法支持原生混淆加密,标准基座或自定义基座真机运行也不支持原生混淆加密(只有正式云打包才支持)
具体使用方式如下:
### 配置要混淆的js/nvue文件
打开manifest.json文件,切换到“源码视图”,按不同项目类型进行配置。
#### uni-app项目
uni-app的js运行在独立的jscore中,而不是webview中,所以不受iOS平台WKWebview不支持原生混淆的限制。
uni-app的vue页面中的js,是整体编译到一个大js文件中的,它经过编译,已经不再是vue源码了,但还不是乱码。对这个统一的大文件进行混淆会有影响性能。
所以uni-app只支持独立混淆nvue/js文件。
- vue页面
HBuilderX2.6.3+版本[v3编译器](https://ask.dcloud.net.cn/article/36599)支持对独立的js文件进行原生混淆,开发者可以将要保护的js代码写到独立的js文件中,在vue页面中使用import引用;如果此js同时被nvue页面import引用,则nvue页面也需要配置原生混淆才有效。另外main.js也可以原生混淆。
老版本不支持vue页面的原生混淆,开发者只能将要保护的js代码写到nvue文件中进行保护。
- nvue页面
HBuilderX2.3.4+版本支持nvue文件的原生混淆。
如果nvue页面引入了外部的js文件,会被一起原生混淆。但如果这个js还被其他不加密的文件引用,则该js仍然会暴露在安装包中。
- vue页面和nvue页面同时使用加密js里的数据或方法(HBuilderX2.6.3+版本v3编译器)
配置该js加密,并在App.vue中引用该js,把该js中的数据或方法赋值给全局对象,如globalData,vue和nvue中通过访问getApp访问共享数据或方法即可,无需配置nvue页面加密。
如果要发布多端的话,要保护的js最好写在app-plus的条件编译中,否则发布到其他端,还是无法原生混淆。
**HBuilderX2.3.4版本开始,uni-app项目支持对nvue文件进行原生混淆**
在"app-plus" -> "confusion" -> "resources"节点下添加要混淆的nvue文件列表:
```javascript
"app-plus": {
"confusion": {
"description": "NVUE原生混淆",
"resources": {
"pages/barcode/barcode.nvue": {
},
"pages/map/map.nvue": {
}
}
},
// ...
}
```
resource下的键名为nvue文件路径(相对于应用根目录),值为空JSON对象(大括号)。
<a id="vuejs"/>
**HBuilderX2.6.3+版本开始,uni-app项目使用[v3编译器](https://ask.dcloud.net.cn/article/36599)支持对vue页面中引用的js文件进行原生混淆**
在manifest.json文件中添加要混淆的js文件列表:
```javascript
"app-plus": {
"confusion": {
"description": "原生混淆",
"resources": {
"common/test.js" : {}
}
},
// ...
}
```
在vue文件中引用混淆的js文件:
```
import test from '../common/test.js';
//test.join(); //调用引用js中的方法
```
**注意:uni-app中vue页面的webview组件支持加载使用加密混淆hybrid、static目录中的js文件,nvue页面的webview组件不支持。**
#### 5+ App/Wap2App项目
应用运行期间在页面打开时需要消耗更多时间进行混淆文件还原,为减少对运行速度的影响,5+App/wap2app仅支持对js文件进行原生混淆。
在"plus" -> "confusion" -> "resources"节点下添加要混淆的js文件列表:
```javascript
"plus": {
"confusion": {
"description": "JS原生混淆",
"resources": {
"js/common.js": {
},
"js/immersed.js": {
}
}
},
// ...
}
```
resource下的键名为js文件路径(相对于应用根目录),值为空JSON对象(大括号)。
<a id="wkwebview"></a>
**HBuilderX2.6.11+版本开始,在iOS11+设备上使用WKWebview也可以支持JS原生混淆**
WKWebview使用了更加严格的安全机制,使用原生混淆的js文件在html页面中必须使用自定义协议头plus-confusion://来引用:
```html
<script type="text/javascript" src="plus-confusion://../js/common.js"></script>
<!-- plus-confusion://后面为js文件路径,相对于当前html页面的路径 -->
```
在manifest.json的"plus" -> "confusion" -> "resources"节点下添加要混淆的js文件列表。
在"confusion"节点下添加 "supportWKWebview": true 支持WKWebview。
由于自定义协议仅在iOS11及以上设备才支持,建议配置应用支持的最低版本[deploymentTarget](https://ask.dcloud.net.cn/article/94#deploymentTarget)为11.0:
```json
"plus": {
"confusion": {
"description": "JS原生混淆",
"supportWKWebview": true,
"resources": {
"js/common.js": {
}
}
},
"distribute": {
"apple": {
"deploymentTarget": "11.0" //设置应用仅支持iOS11及以上设备
//...
}
}
// ...
}
```
**注意:iOS平台WKWebview需iOS11+系统才支持原生混淆。5+App/wap2app项目,如果要兼容iOS11以下设备只能强制使用UIWebview内核,但苹果将要废弃UIWebview([详情](https://ask.dcloud.net.cn/article/36348))。如对原生混淆很重视,从长远考虑,建议改造升级uni-app**
### 提交云端打包
配置好原生混淆的文件列表后,需要提交云端打包,**注意在App云端打包对话框中需要勾选“对配置的js文件进行原生混淆”**
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/sec/confusion.png)
**再次强调:为了保证加密数据的安全性,加密算法和key不对外公开,因此离线打包无法支持原生混淆。**
熟悉原生的开发者可将敏感信息存放于原生代码中,再与js进行交互。
对安全性要求较高的开发者,除了对前端js进行加密外,还应该对整个apk再进行一次加固。市面上很多加固服务可以选择,比如360加固、爱加密等。
......@@ -558,7 +558,7 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**本地宝:** 本地宝(bendibao.com)是领先的便民信息服务平台。[官网App下载](http://www.bendibao.com/app/pc.html)、微信小程序搜索“本地宝”
**不同:** 社交App,遇见价值观相同的知己。nvue优秀体验。[Android](https://a.app.qq.com/o/simple.jsp?pkgname=com.butongapp.butong)[iOS](https://apps.apple.com/cn/app/%E4%B8%8D%E5%90%8C-%E4%BB%B7%E5%80%BC%E8%A7%82%E7%A4%BE%E5%8C%BA/id1476537831
**人生手册:** 社交App,交流人生话题,遇见三观相同的知己。nvue优秀体验。[Android](https://a.app.qq.com/o/simple.jsp?pkgname=com.butongapp.butong)[iOS](https://apps.apple.com/cn/app/%E4%B8%8D%E5%90%8C-%E4%BB%B7%E5%80%BC%E8%A7%82%E7%A4%BE%E5%8C%BA/id1476537831
)
**仓鼠团:** 囤好货到仓鼠,仓鼠团您身边的购物助手。[App通用链接](http://m3w.cn/cst)
......
......@@ -108,6 +108,8 @@
- [发布心情](https://ext.dcloud.net.cn/plugin?id=489)
- [租房小程序](https://gitee.com/cookieBoy/house)
mpvue的所有开源资源都可以用于uni-app。下文汇总收集了网友开源的各种mpvue项目,涵盖了各种业务场景。
- mpvue 开源项目汇总:[https://ask.dcloud.net.cn/article/34945](https://ask.dcloud.net.cn/article/34945)
......
......@@ -229,7 +229,7 @@ data数据是可遍历嵌套的数据集合。数组中每条数据如下基本k
<template>
<!-- 传入符合 datacom 规范的数据,即可渲染出一个选择器 -->
<!-- 使用 v-model 双向绑定 picker 的选中值 -->
<uni-data-picker v-model="value" :localdata="items"></uni-data-checkbox>
<uni-data-picker v-model="value" :localdata="items"></uni-data-picker>
</template>
<script>
export default {
......@@ -441,7 +441,7 @@ mixin是vue的技术,不熟悉的可以点此了解[vue官网的mixin文档](h
<view v-else-if="mixinDatacomErrorMessage">
请求错误:{{mixinDatacomErrorMessage}}
</view>
<view else="mixinDatacomResData">
<view v-else="mixinDatacomResData">
<!-- 需要自行处理数据及相关UI展现 -->
{{mixinDatacomResData}}
</view>
......@@ -491,7 +491,7 @@ mixin是vue的技术,不熟悉的可以点此了解[vue官网的mixin文档](h
<view v-else-if="mixinDatacomErrorMessage">
请求错误:{{mixinDatacomErrorMessage}}
</view>
<view else="mixinDatacomResData">
<view v-else="mixinDatacomResData">
<!-- 需要自行处理数据及相关UI展现 -->
{{mixinDatacomResData}}
</view>
......
......@@ -18,7 +18,7 @@
**属性说明**
|属性|类型|默认值|必填|说明|版本要求
|属性|类型|默认值|必填|说明|版本要求/平台差异说明|
|:-|:-|:-|:-|:-|:-|
|background-text-style|string||否|下拉背景字体、loading 图的样式,仅支持 dark 和 light|微信基础库 2.9.0|
|background-color|string||否|窗口的背景色,必须为十六进制颜色值|微信基础库 2.9.0|
......
......@@ -61,7 +61,7 @@ $uni-primary-light: #d4e4ff;
<div class="color-main margin">
<div class="color-main-top" style="background-color:#e43d33;">
<p class="color-main-text">Error Color</p>
<p class="color-main-text">#e43d33;</p>
<p class="color-main-text">#e43d33</p>
</div>
<div class="color-main-box">
<div class="color-main-top" style="background-color:#f29e99;">
......
# 设计资源
我们提供uni-ui组件的Sketch设计资源,您可以根据需要进行下载。
Axurez资源正在整理和完善中。
Axure资源正在整理和完善中。
<div style="width:260px;border:1px #eee solid; padding:15px;border-radius:5px;text-align: center;">
<img style="width:120px;height:120px;margin:30px auto;" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9Ijg4cHgiIGhlaWdodD0iNzdweCIgdmlld0JveD0iMCAwIDg4IDc3IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCAzOS4xICgzMTcyMCkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+U2tldGNoIFRlbXBsYXRlX2ljb248L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz48L2RlZnM+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iU2tldGNoLVRlbXBsYXRlX2ljb24iPgogICAgICAgICAgICA8ZyBpZD0iR3JvdXAtMjUiPgogICAgICAgICAgICAgICAgPGcgaWQ9ImJyb3dzZXIiPgogICAgICAgICAgICAgICAgICAgIDxnIGlkPSJHcm91cCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wNDI3MzUsIDYuNzcyMjY5KSIgZmlsbD0iI0M5RTFGQiIgb3BhY2l0eT0iMC4yMzg4MDU5NyI+CiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0zLjIwMDg4NDc2LDI4LjUwNTczMzcgTDQ0LjE3MDEzOTEsMjguNTA1NzMzNyBDNDUuOTEwNTI2NSwyOC41MDU3MzM3IDQ3LjMyMTc1NzUsMjcuMTAyNjMxMiA0Ny4zMjE3NTc1LDI1LjM3MjI2ODIgTDQ3LjMyMTc1NzUsMC4zMDU2MDg3MjUgQzQ3LjMyMTc1NzUsMi4wMzU5NzE3MiA0NS45MTA1MjY1LDMuNDM5MDc0MjYgNDQuMTcwMTM5MSwzLjQzOTA3NDI2IEwzLjIwMDg4NDc2LDMuNDM5MDc0MjYgQzEuNDYwNDk3MzksMy40MzkwNzQyNiAwLjA0OTI2NjM1MDMsMi4wMzU5NzE3MiAwLjA0OTI2NjM1MDMsMC4zMDU2MDg3MjUgTDAuMDQ5MjY2MzUwMywyNS4zNzIyNjgyIEMwLjA0OTI2NjM1MDMsMjcuMTAyOTg2MSAxLjQ2MDE0MDM4LDI4LjUwNTczMzcgMy4yMDA4ODQ3NiwyOC41MDU3MzM3IEwzLjIwMDg4NDc2LDI4LjUwNTczMzcgWiIgaWQ9IlNoYXBlIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik01OS45MjcxNjAxLDI4LjUwNTczMzcgTDc4LjgzNjE1NjYsMjguNTA1NzMzNyBDODAuNTc2NTQ0LDI4LjUwNTczMzcgODEuOTg3Nzc1LDI3LjEwMjYzMTIgODEuOTg3Nzc1LDI1LjM3MjI2ODIgTDgxLjk4Nzc3NSwwLjMwNTYwODcyNSBDODEuOTg3Nzc1LDIuMDM1OTcxNzIgODAuNTc2NTQ0LDMuNDM5MDc0MjYgNzguODM2MTU2NiwzLjQzOTA3NDI2IEw1OS45MjcxNjAxLDMuNDM5MDc0MjYgQzU4LjE4Njc3MjgsMy40MzkwNzQyNiA1Ni43NzU1NDE3LDIuMDM1OTcxNzIgNTYuNzc1NTQxNywwLjMwNTYwODcyNSBMNTYuNzc1NTQxNywyNS4zNzIyNjgyIEM1Ni43NzU1NDE3LDI3LjEwMjk4NjEgNTguMTg2NzcyOCwyOC41MDU3MzM3IDU5LjkyNzE2MDEsMjguNTA1NzMzNyBMNTkuOTI3MTYwMSwyOC41MDU3MzM3IFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMy4yNDM2MTkyOSwxMC4yMTE2OTg2IEw0NC4yMTI4NzM2LDEwLjIxMTY5ODYgQzQ1Ljk1MzI2MSwxMC4yMTE2OTg2IDQ3LjM2NDQ5Miw4LjgwODU5NjAzIDQ3LjM2NDQ5Miw3LjA3ODIzMzA0IEw0Ny4zNjQ0OTIsMy45NDQ3Njc1MSBDNDcuMzY0NDkyLDIuMjE0NDA0NTEgNDUuOTUzMjYxLDAuODExMzAxOTY5IDQ0LjIxMjg3MzYsMC44MTEzMDE5NjkgTDMuMjQzNjE5MjksMC44MTEzMDE5NjkgQzEuNTAzMjMxOTEsMC44MTEzMDE5NjkgMC4wOTIwMDA4NzY0LDIuMjE0NDA0NTEgMC4wOTIwMDA4NzY0LDMuOTQ0NzY3NTEgTDAuMDkyMDAwODc2NCw3LjA3ODIzMzA0IEMwLjA5MjAwMDg3NjQsOC44MDg1OTYwMyAxLjUwMjg3NDkxLDEwLjIxMTY5ODYgMy4yNDM2MTkyOSwxMC4yMTE2OTg2IEwzLjI0MzYxOTI5LDEwLjIxMTY5ODYgWiIgaWQ9IlNoYXBlIiBmaWxsPSIjRkZENkQyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTU5Ljk2OTg5NDcsMTAuMjExNjk4NiBMNzguODc4ODkxMSwxMC4yMTE2OTg2IEM4MC42MTkyNzg1LDEwLjIxMTY5ODYgODIuMDMwNTA5Niw4LjgwODU5NjAzIDgyLjAzMDUwOTYsNy4wNzgyMzMwNCBMODIuMDMwNTA5NiwzLjk0NDc2NzUxIEM4Mi4wMzA1MDk2LDIuMjE0NDA0NTEgODAuNjE5Mjc4NSwwLjgxMTMwMTk2OSA3OC44Nzg4OTExLDAuODExMzAxOTY5IEw1OS45Njk4OTQ3LDAuODExMzAxOTY5IEM1OC4yMjk1MDczLDAuODExMzAxOTY5IDU2LjgxODI3NjMsMi4yMTQ0MDQ1MSA1Ni44MTgyNzYzLDMuOTQ0NzY3NTEgTDU2LjgxODI3NjMsNy4wNzgyMzMwNCBDNTYuODE4Mjc2Myw4LjgwODU5NjAzIDU4LjIyOTUwNzMsMTAuMjExNjk4NiA1OS45Njk4OTQ3LDEwLjIxMTY5ODYgTDU5Ljk2OTg5NDcsMTAuMjExNjk4NiBaIiBpZD0iU2hhcGUiIGZpbGw9IiMyMEEwRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8ZyBpZD0iR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYuMTExNzc4LCA0NC4zOTY1NzIpIiBmaWxsPSIjQzlFMUZCIiBvcGFjaXR5PSIwLjIzODgwNTk3Ij4KICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTMuNjM5NDk2NTksMjguNDgxNTk3NCBDMy42Mzk0OTY1OSwzMC4yMTE5NjA0IDIuMTM2NTcxMzcsMzEuNjE1MDYyOSAwLjI4MzEwMzAxMywzMS42MTUwNjI5IEw2Mi41NjY3MDg4LDMxLjYxNTA2MjkgQzY0LjQyMDE3NzIsMzEuNjE1MDYyOSA2NS45MjMxMDI0LDMwLjIxMTk2MDQgNjUuOTIzMTAyNCwyOC40ODE1OTc0IEw2NS45MjMxMDI0LDMuNDE0OTM3OTIgQzY1LjkyMzEwMjQsMS42ODQ1NzQ5MiA2NC40MjAxNzcyLDAuMjgxNDcyMzggNjIuNTY2NzA4OCwwLjI4MTQ3MjM4IEwwLjI4MzEwMzAxMywwLjI4MTQ3MjM4IEMyLjEzNjU3MTM3LDAuMjgxNDcyMzggMy42Mzk0OTY1OSwxLjY4NDU3NDkyIDMuNjM5NDk2NTksMy40MTQ5Mzc5MiBMMy42Mzk0OTY1OSwyOC40ODE1OTc0IFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMy4yNDM2MTkyOSw3Ni4wMTEyODAzIEw2LjM5NTIzNzcsNzYuMDExMjgwMyBDOC4xMzU2MjUwOCw3Ni4wMTEyODAzIDkuNTQ2ODU2MTEsNzQuNjA4MTc3OCA5LjU0Njg1NjExLDcyLjg3NzgxNDggTDkuNTQ2ODU2MTEsNDcuODExMTU1MyBDOS41NDY4NTYxMSw0Ni4yNjUwMjEgOC40MjAxMzA2Niw0NC45ODAxNzEyIDYuOTM4NjI2MjgsNDQuNzI0MTA1OSBDNi43NjIwOTg1MSw0NC42OTM1OTQ2IDYuNTgwNTMzNjgsNDQuNjc3Njg5OCA2LjM5NTIzNzcsNDQuNjc3Njg5OCBMMy4yNDM2MTkyOSw0NC42Nzc2ODk4IEMxLjUwMzIzMTkxLDQ0LjY3NzY4OTggMC4wOTIwMDA4NzY0LDQ2LjA4MDc5MjMgMC4wOTIwMDA4NzY0LDQ3LjgxMTE1NTMgTDAuMDkyMDAwODc2NCw3Mi44Nzc4MTQ4IEMwLjA5MjAwMDg3NjQsNzQuNjA4MTc3OCAxLjUwMjg3NDkxLDc2LjAxMTI4MDMgMy4yNDM2MTkyOSw3Ni4wMTEyODAzIEwzLjI0MzYxOTI5LDc2LjAxMTI4MDMgWiIgaWQ9IlNoYXBlIiBmaWxsPSIjMjBBMEZGIj48L3BhdGg+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8ZyBpZD0iZGlhbW9uZCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTMuMDAwMDAwLCA0NS4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiNBRkM4RUIiIHBvaW50cz0iMjQuMTc1MzI2NCA4Ljg2MDY5Nzk1IDE3LjE4NTE4NTIgMjguODM1NzAyNSAzNC4zNzAzNzA0IDguODYwNjk3OTUiPjwvcG9seWdvbj4KICAgICAgICAgICAgICAgICAgICA8ZyBpZD0iR3JvdXAiPgogICAgICAgICAgICAgICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiM4MEE4RTEiIHBvaW50cz0iNy4xMTExMDg4IDAuMDQ4MTg0MTc5NyAwIDguODYwNjk3OTUgMTAuMTk1MDQ0IDguODYwNjk3OTUiPjwvcG9seWdvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPHBvbHlnb24gaWQ9IlNoYXBlIiBmaWxsPSIjODBBOEUxIiBwb2ludHM9IjI0LjE3NTMyNjQgOC44NjA2OTc5NSAzNC4zNzAzNzA0IDguODYwNjk3OTUgMjcuMjU5MjYxNiAwLjA0ODE4NDE3OTciPjwvcG9seWdvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPHBvbHlnb24gaWQ9IlNoYXBlIiBmaWxsPSIjQUZDOEVBIiBwb2ludHM9IjI0LjE3NTMyNjQgOC44NjA2OTc5NSAxNy4xODUxODUyIDAuMDQ4MTg0MTc5NyAxMC4xOTUwNDQgOC44NjA2OTc5NSI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiM2NDk2REMiIHBvaW50cz0iMTcuMTg1MTg1MiAwLjA0ODE4NDE3OTcgNy4xMTExMDg4IDAuMDQ4MTg0MTc5NyAxMC4xOTUwNDQgOC44NjA2OTc5NSI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJTaGFwZSIgZmlsbD0iIzkzQjhFRSIgcG9pbnRzPSIyNy4yNTkyNjE2IDAuMDQ4MTg0MTc5NyAxNy4xODUxODUyIDAuMDQ4MTg0MTc5NyAyNC4xNzUzMjY0IDguODYwNjk3OTUiPjwvcG9seWdvbj4KICAgICAgICAgICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiM4MEE4RTEiIHBvaW50cz0iMTAuMTk1MDQ0IDguODYwNjk3OTUgMTcuMTg1MTg1MiAyOC44MzU3MDI1IDI0LjE3NTMyNjQgOC44NjA2OTc5NSI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJTaGFwZSIgZmlsbD0iIzY0OTZEQyIgcG9pbnRzPSIwIDguODYwNjk3OTUgMTcuMTg1MTg1MiAyOC44MzU3MDI1IDEwLjE5NTA0NCA4Ljg2MDY5Nzk1Ij48L3BvbHlnb24+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==">
......
......@@ -14,7 +14,7 @@
```html
<uni-badge size="small" :text="100" absolute="rightBottom" type="primary">
<button type="default"></button>
<button type="default"></button>
</uni-badge>
<uni-badge text="1"></uni-badge>
<uni-badge text="2" type="purple" @click="bindClick"></uni-badge>
......
......@@ -73,7 +73,7 @@
```css
@font-face {
font-family: "iconfont";
src: url('./iconfont.ttf') format('truetype');
src: url('/static/iconfont.ttf') format('truetype');
}
.iconfont {
......
......@@ -32,7 +32,7 @@ uni-link是一个外部网页超链接组件,在小程序内复制url,在app
|名称|说明|
|:-:|:-:|
|default|自定义内容,覆盖原有的内容显示(仅 vue 支持)|
|default|自定义内容,覆盖原有的内容显示(仅 vue 支持)|
## 组件示例
......
......@@ -201,6 +201,7 @@ export default {
|showBadge|Boolean|false|是否显示数字角标 |
|badgeText|String|-|数字角标内容|
|badgeType|String|-|数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21) |
|badgeStyle |Object |- | 数字角标样式,使用uni-badge的custom-style参数|
|rightText|String|-|右侧文字内容|
|disabled|Boolean|false|是否禁用 |
|showArrow|Boolean|true|是否显示箭头图标 |
......
......@@ -14,7 +14,7 @@
<uni-search-bar @confirm="search" @input="input" ></uni-search-bar>
<!-- v-model 用法 -->
<uni-search-bar @confirm="search" :focus="true" v-model="searchValue" @blur="blur" @focus="focus" @input="input" @cancel="cancel" @change="change" @clear="clear">
<uni-search-bar @confirm="search" :focus="true" v-model="searchValue" @blur="blur" @focus="focus" @input="input" @cancel="cancel" @change="change" @clear="clear"></uni-search-bar>
<!-- 自定义Placeholder -->
<uni-search-bar placeholder="自定placeholder" @confirm="search"></uni-search-bar>
......
......@@ -29,6 +29,29 @@
</template>
```
```html
<script>
export default {
data() {
return {
...
items: ['选项1', '选项2', '选项3'],
current: 0
};
},
methods: {
...
onClickItem(e) {
if (this.current != e.currentIndex) {
this.current = e.currentIndex;
}
}
}
};
</script>
```
## API
### SegmentedControl Props
......
......@@ -139,7 +139,7 @@ HBuilderX 2.7.10+ 版支持
* 使用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](https://ask.dcloud.net.cn/article/35451)
* 发布App时,仍然需要使用HBuilderX。其他开发工具无法发布App,但可以发布H5、各种小程序。如需开发App,可以先在HBuilderX里运行起来,然后在其他编辑器里修改保存代码,代码修改后会自动同步到手机基座。
* 如果使用``cli``创建项目,那下载HBuilderX时只需下载10M的标准版即可。因为编译器已经安装到项目下了。
* 如果使用``cli``创建项目,那下载HBuilderX时只需下载23.31M的标准版即可。因为编译器已经安装到项目下了。
*`cli` 使用有疑问,欢迎扫码加入 uni-app 微信交流群讨论:
<br/><img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/wx-barcode.png" width="250"/>
......
......@@ -185,7 +185,7 @@ iOS App打包需要向Apple申请证书。
**发布为字节跳动小程序:**
1. 入驻字节跳动小程序,参考:[字节跳动小程序教程](https://developer.toutiao.com/dev/cn/mini-app/introduction/plug-in/registration)
2. 在HBuilderX中顶部菜单依次点击 "发行" => "小程序-字节跳动",即可在 ``/unpackage/dist/build/mp-alipay`` 生成字节跳动小程序项目代码。
2. 在HBuilderX中顶部菜单依次点击 "发行" => "小程序-字节跳动",即可在 ``/unpackage/dist/build/mp-toutiao`` 生成字节跳动小程序项目代码。
<div align=center>
<img style="max-width:300px;" src="https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/a6ba4ed0-4f39-11eb-b997-9918a5dda011.jpg"/>
</div>
......
......@@ -47,7 +47,7 @@ App端定位模块封装系统自带的`系统定位`,及市场上主流的三
### 高德定位
> 需要向高德申请商业授权,参考:[商业授权相关说明](id=business),使用前需登录 [高德开放平台](https://lbs.amap.com/) 创建应用申请Key
> 需要向高德申请商业授权,参考:[商业授权相关说明](app-geolocation?id=business),使用前需登录 [高德开放平台](https://lbs.amap.com/) 创建应用申请Key
使用`高德定位`需在“App模块配置”项的“Geolocation(定位)”下,勾选“高德定位”:
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/geolocation/amap.png)
......@@ -66,7 +66,7 @@ App端定位模块封装系统自带的`系统定位`,及市场上主流的三
### 百度定位
> 需要向百度申请商业授权,参考:[商业授权相关说明](id=business),使用前需登录 [百度地图开放平台](https://lbsyun.baidu.com/) 创建应用申请访问应用密钥(AK)
> 需要向百度申请商业授权,参考:[商业授权相关说明](app-geolocation?id=business),使用前需登录 [百度地图开放平台](https://lbsyun.baidu.com/) 创建应用申请访问应用密钥(AK)
使用`高德定位`需在“App模块配置”项的“Geolocation(定位)”下,勾选“百度定位”:
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/geolocation/baidu.png)
......
......@@ -88,7 +88,7 @@ UniPush模块用到个推SDK,内部功能涉及到CustomGTService、PushReceiv
**修复方案**
HBuilderX3.0.0+版本新增[plus.navigator.getSignature](https://www.html5plus.org/doc/zh_cn/navigator.html#plus.navigator.getSignature)方法获取Android平台签名证书的SHA-1指纹信息,在应用启动或运行时进行校验判断。
可以在应用运行期间定时校验,以下是uni-app项目在App.vue的应用生命周期[onLaunch](https://uniapp.dcloud.io/collocation/App.html#应用生命周期)中进行校验,示例如下:
可以在应用运行期间定时校验,以下是uni-app项目在App.vue的应用生命周期[onLaunch](https://uniapp.dcloud.io/collocation/frame/lifecycle?id=%e5%ba%94%e7%94%a8%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f)中进行校验,示例如下:
``` js
onLaunch: function(inf) {
console.log('App Launch');
......@@ -104,7 +104,7 @@ HBuilderX3.0.0+版本新增[plus.navigator.getSignature](https://www.html5plus.o
```
> 提示:为了防止js检验代码被反编译篡改,建议将签名校验代码放到独立js文件中并配置[JS/NVUE文件原生混淆加密](https://ask.dcloud.net.cn/article/36437),或者使用apk加固处理
> 提示:为了防止js检验代码被反编译篡改,建议将签名校验代码放到独立js文件中并配置[js/nvue文件原生混淆加密](app-sec-confusion),或者使用apk加固处理
#### APK可被反编译后取得源代码风险
......@@ -135,3 +135,9 @@ HBuilderX发布到App的Android平台最低支持Android4.4,即minSdkVersion
**修复方案**
HBuilderX3.1.14+版本已修复此问题,在内部逻辑中使用的密钥全部做了混淆加密处理。
#### SO文件破解风险漏洞
**风险描述**
SO文件为APK中包含的动态链接库文件,Android利用NDK技术将C/C++语言实现的核心代码编译为SO库文件供Java层调用。SO文件被破解可能导致应用的核心功能代码和算法泄露。攻击者利用核心功能与算法可轻易抓取到客户端的敏感数据,并对其解密,导致用户的隐私泄露或直接财产损失
**修复方案**
建议使用专业安全加固平台对APK中的SO文件进行加固保护
......@@ -284,3 +284,57 @@
},
});
```
- uni-app 生命周期钩子在 Vue3 组合式 API 中的使用方式如下:
- 在 Vue3 组合式 API 中,也需要遵循 uni-app 生命周期钩子规范, 如 onLaunch 等应用生命周期仅可在 App.vue 中监听,使用中请注意生命周期钩子的适用范围。[查看全部生命周期钩子](https://uniapp.dcloud.net.cn/collocation/frame/lifecycle)
- 只能在 `<script setup>` 单文件语法糖或 `setup()` 方法中使用生命周期钩子,以 A 页面跳转 B 页面传递参数为例:
```js
// 从 A 页面跳转 B 页面时传递参数 ?id=1&name=uniapp,xxx 为跳转的页面路径
//uni.navigateTo({
// url: 'xxx?id=1&name=uniapp'
//})
// 方式一:在 B 页面 <script setup> 中
<script setup>
import {
onLoad,
onShow
} from "@dcloudio/uni-app";
// onLoad 接受 A 页面传递的参数
onLoad((option) => {
console.log("B 页面 onLoad:", option); //B 页面 onLoad: {id: '1', name: 'uniapp'}
});
onShow(() => {
console.log("B 页面 onShow");
});
</script>
```
```js
// 方式二:在 B 页面 setup() 中
<script>
import {
onLoad,
onShow,
} from "@dcloudio/uni-app";
export default {
setup() {
// onLoad 接受 A 页面传递的参数
onLoad((option) => {
console.log("B 页面 onLoad:", option); //B 页面 onLoad: {id: '1', name: 'uniapp'}
});
onShow(() => {
console.log("B 页面 onShow");
});
}
}
</script>
```
\ No newline at end of file
......@@ -205,6 +205,32 @@ HBuilderX 内置了 weex 调试工具的强化版,包括审查界面元素、
示例工程[点击下载](https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/d5adb160-55af-11eb-bd01-97bc1429a9ff.zip)
## nvue开发与vue开发的常见区别
基于原生引擎的渲染,虽然还是前端技术栈,但和web开发肯定是有区别的。
1. nvue 页面控制显隐只可以使用```v-if```不可以使用```v-show```
2. nvue 页面只能使用``` flex ```布局,不支持其他布局方式。页面开发前,首先想清楚这个页面的纵向内容有什么,哪些是要滚动的,然后每个纵向内容的横轴排布有什么,按 flex 布局设计好界面。
3. nvue 页面的布局排列方向默认为竖排(```column```),如需改变布局方向,可以在 ```manifest.json``` -> ```app-plus``` -> ```nvue``` -> ```flex-direction``` 节点下修改,仅在 uni-app 模式下生效。[详情](https://uniapp.dcloud.io/collocation/manifest?id=nvue)
4. nvue页面编译为H5、小程序时,会做一件css默认值对齐的工作。因为weex渲染引擎只支持flex,并且默认flex方向是垂直。而H5和小程序端,使用web渲染,默认不是flex,并且设置```display:flex```后,它的flex方向默认是水平而不是垂直的。所以nvue编译为H5、小程序时,会自动把页面默认布局设为flex、方向为垂直。当然开发者手动设置后会覆盖默认设置。
5. 文字内容,必须、只能在```<text>```组件下。不能在```<div>``````<view>``````text```区域里直接写文字。否则即使渲染了,也无法绑定js里的变量。
6. 只有```text```标签可以设置字体大小,字体颜色。
7. 布局不能使用百分比、没有媒体查询。
8. nvue 切换横竖屏时可能导致样式出现问题,建议有 nvue 的页面锁定手机方向。
9. 支持的css有限,不过并不影响布局出你需要的界面,```flex```还是非常强大的。[详见](/nvue-css?id=flex)
10. 不支持背景图。但可以使用```image```组件和层级来实现类似web中的背景效果。因为原生开发本身也没有web这种背景图概念
11. css选择器支持的比较少,只能使用 class 选择器。[详见](/nvue-css)
12. nvue 的各组件在安卓端默认是透明的,如果不设置```background-color```,可能会导致出现重影的问题。
13. ```class``` 进行绑定时只支持数组语法。
14. Android端在一个页面内使用大量圆角边框会造成性能问题,尤其是多个角的样式还不一样的话更耗费性能。应避免这类使用。
15. nvue页面没有```bounce```回弹效果,只有几个列表组件有```bounce```效果,包括 ```list``````recycle-list``````waterfall```
16. 原生开发没有页面滚动的概念,页面内容高过屏幕高度并不会自动滚动,只有部分组件可滚动(```list``````waterfall``````scroll-view/scroller```),要滚的内容需要套在可滚动组件下。这不符合前端开发的习惯,所以在 nvue 编译为 uni-app模式时,给页面外层自动套了一个 ```scroller```,页面内容过高会自动滚动。(组件不会套,页面有```recycle-list```时也不会套)。后续会提供配置,可以设置不自动套。
17. 在 App.vue 中定义的全局js变量不会在 nvue 页面生效。```globalData``````vuex```是生效的。
18. App.vue 中定义的全局css,对nvue和vue页面同时生效。如果全局css中有些css在nvue下不支持,编译时控制台会报警,建议把这些不支持的css包裹在[条件编译](https://uniapp.dcloud.io/platform)里,```APP-PLUS-NVUE```
19. 不能在 ```style``` 中引入字体文件,nvue 中字体图标的使用参考:[加载自定义字体](/nvue-api?id=addrule)。如果是本地字体,可以用```plus.io```的API转换路径。
20. 目前不支持在 nvue 页面使用 ```typescript/ts```
21. nvue 页面关闭原生导航栏时,想要模拟状态栏,可以[参考文章](https://ask.dcloud.net.cn/article/35111)。但是,仍然强烈建议在nvue页面使用原生导航栏。nvue的渲染速度再快,也没有原生导航栏快。原生排版引擎解析```json```绘制原生导航栏耗时很少,而解析nvue的js绘制整个页面的耗时要大的多,尤其在新页面进入动画期间,对于复杂页面,没有原生导航栏会在动画期间产生整个屏幕的白屏或闪屏。
## iOS 平台下拉组件 refresh 组件注意问题
iOS 平台默认情况下滚动容器组件(如`list``waterfall`组件)内容不足时,由于没有撑满容器的可视区域会导致无法上下滚动,此时无法操作下拉刷新功能,无法触发`refresh`组件的`@refresh``@pullingdown`事件。 此时可在容器组件中配置`alwaysScrollableVertical`属性值为`true`来设置支持上下滚动,支持下拉刷新操作。
......
......@@ -225,7 +225,7 @@ uni-app自带的web-view组件,是页面中新插入的一个子webview。获
### uni.$emit(eventName,OBJECT) @emit
触发全局的自定事件。附加参数都会传给监听器回调。
触发全局的自定事件。附加参数都会传给监听器回调。
|属性 |类型 |描述 |
|--- |--- |--- |
......
......@@ -581,7 +581,7 @@
<!-- 我是子组件date-picker -->
<template>
<view class="date-picker">
<input type="datetime" />
<input type="datetime-local" />
</view>
</template>
```
......@@ -595,7 +595,7 @@
<!-- 渲染 date-picker 组件 -->
<div class="date-picker" data-status="activated">
<input type="datetime" />
<input type="datetime-local" />
</div>
```
......@@ -667,7 +667,7 @@
```html
<template>
<view class="date-picker">
<input type="datetime" v-bind="$attrs" />
<input type="datetime-local" v-bind="$attrs" />
</view>
</template>
<script>
......@@ -685,7 +685,7 @@
<!-- 渲染 date-picker 组件 -->
<view class="date-picker">
<input type="datetime" data-status="activated" />
<input type="datetime-local" data-status="activated" />
</view>
```
......
......@@ -38,7 +38,7 @@
* [日志输出](uniCloud/cf-logger.md)
* [客户端sdk](uniCloud/client-sdk.md)
* 增强开源库
* [uni-config-center 配置中心](https://ext.dcloud.net.cn/plugin?id=4425)
* [uni-config-center 配置中心](uniCloud/uni-config-center.md)
* [uni-starter](https://ext.dcloud.net.cn/plugin?id=5057)
* [uni-admin](uniCloud/admin.md)
* [uni-upgrade-center App升级中心](uniCloud/upgrade-center.md)
......
......@@ -43,6 +43,8 @@ doc(docId)方法的参数只能是字符串,即数据库默认的_id字段。
如需要匹配多个`_id`的记录,应使用where方法。可以在where方法里用in指令匹配一个包含`_id`的数组。
新增文档时数据库会自动生成_id字段,也可以自行将_id设置为其他值
### 查询筛选指令 Query Command@query-command
以下指令挂载在 `db.command`
......@@ -2001,29 +2003,29 @@ db.collection('scores').aggregate()
- 聚合操作实例仅用于查询,不可执行增删改操作。在聚合操作实例上只能使用聚合操作方法,不能使用where/orderBy等基础方法,where需改为match,orderBy应使用sort实现,细节请阅读下方聚合操作文档。
- 聚合操作在大数据量下性能不如简单查询,请根据自身业务选择合适的用法
云函数中使用时切勿复用aggregate实例,容易引发Bug。
云函数中使用时切勿复用aggregate实例,容易引发Bug。
以下两种写法均为错误示例:
```js
const db = uniCloud.database()
const collection = db.collection('test')
const aggregate = collection.aggregate() // 云函数实例复用时,此聚合实例也会复用,导致Bug
exports.main = async function(){
const res = await aggregate.match({a:1}).end()
return {res}
}
```
```js
const db = uniCloud.database()
const collection = db.collection('test')
exports.main = async function(){
const aggregate = collection.aggregate() // 此聚合实例分别在两个请求内使用,导致Bug
const res1 = await aggregate.match({a:1}).end()
const res2 = await aggregate.match({a:2}).end()
return {res1, res2}
}
```js
const db = uniCloud.database()
const collection = db.collection('test')
const aggregate = collection.aggregate() // 云函数实例复用时,此聚合实例也会复用,导致Bug
exports.main = async function(){
const res = await aggregate.match({a:1}).end()
return {res}
}
```
```js
const db = uniCloud.database()
const collection = db.collection('test')
exports.main = async function(){
const aggregate = collection.aggregate() // 此聚合实例分别在两个请求内使用,导致Bug
const res1 = await aggregate.match({a:1}).end()
const res2 = await aggregate.match({a:2}).end()
return {res1, res2}
}
```
### 聚合表达式@aggregate-expression
......@@ -3396,34 +3398,35 @@ let res = await db.collection('orders').aggregate()
如需orders关联books,book再关联authors查询,可以在pipeline内再使用lookup
```js
const db = cloud.database()
const $ = db.command.aggregate
let res = await db.collection('orders').aggregate()
.lookup({
from: 'books',
let: {
book_id: '$book'
},
pipeline: $.pipeline()
.match(
$.expr($.eq(['$_id', '$$book_id']))
)
.lookup({
from: 'authors',
let: {
author_id: '$author'
},
pipeline: $.pipeline()
.match(
$.expr($.eq(['$_id', '$$author_id']))
)
.done(),
as: 'authorList'
})
.done(),
as: 'bookList',
})
.end()
const db = cloud.database()
const dbCmd = db.command
const $ = db.command.aggregate
let res = await db.collection('orders').aggregate()
.lookup({
from: 'books',
let: {
book_id: '$book'
},
pipeline: $.pipeline()
.match(
dbCmd.expr($.eq(['$_id', '$$book_id']))
)
.lookup({
from: 'authors',
let: {
author_id: '$author'
},
pipeline: $.pipeline()
.match(
dbCmd.expr($.eq(['$_id', '$$author_id']))
)
.done(),
as: 'authorList'
})
.done(),
as: 'bookList',
})
.end()
```
......@@ -5312,9 +5315,9 @@ let res = await db.collection('todos').doc('doc-id').update({
#### abs
<!--
/// meta
keyword: abs,绝对值
<!--
/// meta
keyword: abs,绝对值
-->
返回一个数字的绝对值。
......@@ -5366,9 +5369,9 @@ let res = await db.collection('ratings').aggregate()
#### add
<!--
/// meta
keyword: 相加,add,日期
<!--
/// meta
keyword: 相加,add,日期
-->
将数字相加或将数字加在日期上。如果数组中的其中一个值是日期,那么其他值将被视为毫秒数加在该日期上。
......@@ -6077,7 +6080,7 @@ db.command.aggregate.arrayToObject([
{ "_id": 2, "sales": [ ["max", 70], ["min", 60] ] }
{ "_id": 3, "sales": [ { "k": "max", "v": 50 }, { "k": "min", "v": 30 } ] }
```
求各个第一次考试的分数和和最后一次的分数
将数组转换为对象
```js
......@@ -9536,9 +9539,9 @@ let res = await db
#### avg
<!--
/// meta
keyword: 均值
<!--
/// meta
keyword: 均值
-->
返回一组集合中,指定字段对应数据的平均值。
......@@ -9934,9 +9937,9 @@ let res = await db.collection('students').aggregate()
#### sum
<!--
/// meta
keyword: 求和
<!--
/// meta
keyword: 求和
-->
计算并且返回一组字段所有数值的总和。
......
......@@ -197,7 +197,7 @@ exports.main = async (event, context) => {
但为了方便拦截器统一处理返回值,捕获异常或弹框提示,uniCloud定义了`uniCloud响应体规范`,推荐开发者使用。
`uniCloud响应体规范`(uniCloud response format),是DCloud制定的、服务器给客户端返回json数据的一种建议格式。后续uni-id、uni-pay、clientDB等均会调整为此结构
`uniCloud响应体规范`(uniCloud response format),是DCloud制定的、服务器给客户端返回json数据的一种建议格式。uni-id公共模块已支持此规范,后续uni-pay、clientDB等均会调整为此结构
**由来**
......@@ -387,11 +387,11 @@ exports.main = async (event, context) => {
Tips:
- 目前每个云函数上传包大小限制为10M。如果npm包很大,阿里云的整体上传机制会无法满足需求。此时只能选择腾讯云,交给腾讯云自动安装依赖。
## 公共模块
## 公共模块@common
云函数支持公共模块。多个云函数的共享部分,可以抽离为公共模块,然后被多个云函数引用。[详见](uniCloud/cf-common)
## 扩展库
## 扩展库@extension
uniCloud的api中,有些api对应的实现,其源码体积较大,且这些功能并不是每一个云函数都会使用。为了方面开发者控制云函数的体积,设计了`uniCloud扩展库`的概念。
......@@ -486,6 +486,27 @@ let callFunctionResult = await uniCloud.callFunction({
})
```
### 云函数内调用其他服务空间的云函数@call-by-function-cross-space
> 仅腾讯云支持
在腾讯云服务空间的云函数内支持获取同账号下其他服务空间的uniCloud实例,参考:[一个应用访问多个服务空间](uniCloud/concepts/space.md?id=multi-space),并使用此实例调用对应服务空间的云函数。
```javascript
//开发者创建了多个服务空间,则需手动初始化。注意这是前端代码,不是云函数代码
const myCloud = uniCloud.init({
provider: 'tencent',
spaceId: 'xxxx-yyy'
});
//通过uniCloud实例调用云开发的API
myCloud.callFunction()
myCloud.uploadFile()
```
**注意**
- 连接本地云函数调试时,如果存在跨服务空间调用,则callFunction会使用云端云函数
## 开发模式
实际项目中,很少会每个接口新建一个云函数。
......
......@@ -2,9 +2,9 @@
> 新增于 HBuilderX 3.4.0
云对象本质上是对云函数的封装,和传统方式通过callFunction调用云函数相比,云对象写法更简单,调用更清晰。另外云对象默认支持[uniCloud响应体规范](uniCloud/cf-functions.md?id=resformat),对于满足规范的错误响应会在客户端自动抛出错误,开发者可以少写很多罗里吧嗦的判断。
云对象本质上是对云函数的封装,和传统方式通过callFunction调用云函数相比,云对象写法更简单,调用更清晰。另外云对象默认支持[uniCloud响应体规范](uniCloud/cf-functions.md?id=resformat),对于满足规范的错误响应会在客户端自动抛出错误,开发者可以少写很多繁琐的判断。
多action云函数为例,对比一下云对象和传统云函数
下面的云函数为例,对比一下云对象和传统云函数
**传统callFunction方式代码如下:**
......@@ -15,44 +15,45 @@
'use strict';
exports.main = async (event, context) => {
const {
action,
method,
params
} = event
switch(action) {
case 'updateUser': {
switch(method) {
case 'login': {
const {
nickname,
age
username,
password
} = params
// 简化演示逻辑,此处不演示token校验
if(!nickname) {
if(!username) {
return {
errCode: 'INVALID_NICKNAME',
errMsg: '昵称不正确'
errCode: 'INVALID_USERNAME',
errMsg: '用户名不正确'
}
}
// ...省略其他逻辑
return {
errCode: 0,
errMsg: '更新成功'
errMsg: '登录成功'
}
}
}
return {
errCode: 'ACTION_NOT_FOUND',
errMsg: `action[action] not found`
errCode: 'METHOD_NOT_FOUND',
errMsg: `Method[${method}] not found`
}
};
// 传统方式调用云函数-客户端代码
async function updateUser () {
async function login () {
try {
const res = uniCloud.callFunction({
name: 'user-center',
data: {
action: 'updateUser',
method: 'login',
params: {
nickname: 'dc',
age: 10
username: 'dc',
password: '123456'
}
}
})
......@@ -62,18 +63,18 @@ async function updateUser () {
} = res.result
if(errCode) {
uni.showModal({
title: '更新失败',
title: '登录失败',
content: errMsg,
showCancel: false
})
return
}
uni.showToast({
title: '更新成功'
title: '登录成功'
})
} catch (e) {
uni.showModal({
title: '更新失败',
title: '登录失败',
content: e.message,
showCancel: false
})
......@@ -88,36 +89,37 @@ async function updateUser () {
// 云对象名:user-center
// 云对象入口index.obj.js内容如下
module.exports = {
updateUser(nickname, age) {
if (!nickname) {
login(username, password) {
if (!username) {
return {
errCode: 'INVALID_NICKNAME',
errMsg: '昵称不正确'
errCode: 'INVALID_USERNAME',
errMsg: '用户名不正确'
}
}
// ...登录逻辑
return {
errCode: 0,
errMsg: '更新成功'
errMsg: '登录成功'
}
}
}
// 使用云对象的写法-客户端代码
const userCenter = uniCloud.importObject('user-center')
async function updateUser () {
async function login () {
try {
const res = await userCenter.updateUser('dc', 10)
const res = await userCenter.login('dc', '123456')
uni.showToast({
title: '更新成功'
title: '登录成功'
})
} catch (e) {
// 此形式响应符合uniCloud响应体规范中的错误响应,自动抛出此错误
// {
// errCode: 'INVALID_NICKNAME',
// errMsg: '昵称不正确'
// errCode: 'INVALID_USERNAME',
// errMsg: '用户名不正确'
// }
uni.showModal({
title: '更新失败',
title: '登录失败',
content: e.errMsg,
showCancel: false
})
......@@ -125,20 +127,20 @@ async function updateUser () {
}
```
可以看到大量的业务无关代码被简化掉,开发效率UP。此外通过`ObjectName.ActionName`的方式调用云函数和云端写法完全一致,心智负担大幅减小。请阅读以下内容深入了解云对象
可以看到大量的业务无关代码被简化掉,开发效率UP。此外通过`ObjectName.MethodName`的方式调用云函数和云端写法完全一致,心智负担大幅减小。请阅读以下内容深入了解云对象
## 规范
云对象和云函数都在cloudfunctions目录下,但是不同于云函数,云对象的入口为`index.obj.js`,而云函数则是`index.js`**为正确区分两者uniCloud做出了限制,云函数内不可存在index.obj.js,云对象内也不可存在index.js。**一个标准的云对象入口应导出一个对象,如下:
对象内每个键值对是一个action
对象内每个键值对是一个处理方法
```js
// user-center/index.obj.js
module.exports = {
updateUser: async function(nickname, age) {
console.log(nickname, age)
} // action updateUser
login: async function(username, password) {
console.log(username, password)
} // login方法
}
```
......@@ -150,10 +152,36 @@ module.exports = {
```js
const userCenter = uniCloud.importObject('user-center')
const res = await userCenter.updateUser('dc', 10) // 传入参数 nickname 和 age,参数和云对象内的action完全一致
const res = await userCenter.login('dc', '123456') // 传入参数 username 和 password,参数和云对象内的方法完全一致
```
### 客户端调用返回值@return-value
### 云函数或云对象内调用@call-by-cloud
云函数或云对象内也可以调用同一服务空间内的云对象,用法和客户端调用云对象一致
```js
const userCenter = uniCloud.importObject('user-center')
const res = await userCenter.login('dc', '123456') // 传入参数 username 和 password,参数和云对象内的方法完全一致
```
### 跨服务空间调用云对象@call-by-cloud-cross-space
云端或者客户端均有uniCloud.init方法可以获取其他服务空间的uniCloud实例,使用此实例的importObject可以调用其他服务空间的云对象,参考:[](uniCloud/concepts/space.md?id=multi-space)
客户端无论腾讯阿里均支持。云端`uniCloud.init`方法仅腾讯云支持,且仅能获取同账号下的腾讯云服务空间的uniCloud实例。
**示例代码**
```js
const mycloud = uniCloud.init({
provider: 'tencent',
spaceId: 'xxx'
})
const userCenter = mycloud.importObject('user-center')
const loginRes = await mycloud.login('dc', '123456')
```
### 云对象的返回值@return-value
客户端拿到云对象的响应结果后,会自动进行结果的处理。
......@@ -175,16 +203,16 @@ const res = await userCenter.updateUser('dc', 10) // 传入参数 nickname 和 a
```js
// user-center/index.obj.js
module.exports = {
updateUser: async function(nickname, age) {
if(!nickname) {
login: async function(username, password) {
if(!username) {
return {
errCode: 'INVALID_NICKNAME',
errMsg: '更新失败'
errCode: 'INVALID_USERNAME',
errMsg: '登录失败'
}
}
return {
errCode: 0,
errMsg: '更新成功'
errMsg: '登录成功'
}
}
}
......@@ -193,17 +221,20 @@ module.exports = {
const userCenter = uniCloud.importObject('user-center')
try {
// 不传username,云函数返回错误的响应
await userCenter.updateUser()
await userCenter.login()
} catch (e) {
// e.errCode === 'INVALID_NICKNAME'
// e.errMsg === '更新失败'
// e.detail === {errCode: 'INVALID_NICKNAME',errMsg: '更新失败'}
// e.errCode === 'INVALID_USERNAME'
// e.errMsg === '登录失败'
// e.detail === {errCode: 'INVALID_USERNAME',errMsg: '登录失败'}
// e.requestId === 'xxxx'
}
try {
const res = await userCenter.updateUser('dc', 10)
const res = await userCenter.login('dc', '123456')
// res = {errCode: 0,errMsg: '更新成功'}
} catch (e) {}
```
## 本地运行@run-local
云对象无法直接本地运行,可以通过其他云函数调用本地云对象(在调用云对象的云函数右键本地运行),或者客户端调用本地云对象的方式来实现云对象的本地运行。
\ No newline at end of file
......@@ -60,9 +60,48 @@ web控制台可以新建、删除服务空间,管理线上的服务空间资
### 多应用共用服务空间@multi-app
比如一个项目的用户端和管理端,在HBuilderX里可以创建成2个项目,但2个项目的服务空间可以指向一个,或者干脆把其中一个项目的服务空间绑定到另一个项目上。
[详见](https://ask.dcloud.net.cn/article/37949)
随着用户使用uniCloud开发的项目越来越多, 部分用户遇到了新的问题。
两个、多个项目想共用一个云服务空间,比如一个系统,有用户端项目、管理admin项目,两个项目需要公共服务空间。还有司机端、乘客端、用户端、骑手端....很多类似的问题。
如果每个项目目录下都存在多个重复的云函数文件。 每个项目都要做 同步云函数列表, 下载云函数等操作。 繁琐,而且很容易冲突。
针对上面出现的问题, 提供了`一云多项目`的解决方案。
#### 一云多端
##### 绑定其它项目的服务空间
选中项目下的`uniCloud-aliyun|tcb`目录, 右键菜单,点击 【关联云服务空间或项目... 】 ,可以`关联云服务空间``绑定其它项目的服务空间`
![](https://img-cdn-tc.dcloud.net.cn/uploads/article/20201207/3ab467421c154e83077bb96f1497dec1.gif)
##### 已关联项目
选择关联项目,此时显示的是所有的uniapp项目。用户选择任一uniapp项目进行关联, 关联效果如下图:
![](https://img-cdn-tc.dcloud.net.cn/uploads/article/20201207/6eab0accfe8fa00b97972b04773df688.png)
1. 查看关联项目的服务空间:点击后,会在项目管理器打开关联的项目
2. 解除绑定:解除绑定,会解除绑定关系,可以重新`关联云服务空间``绑定其它项目的服务空间`
3. 移动至关联项目xxx下: 会将当前项目的uniCloud目录内容,移动到关联的项目下。
##### 插件市场导入插件
![](https://img-cdn-tc.dcloud.net.cn/uploads/article/20201207/0d4ab346f103f0a746801a59b9b51c57.png)
#### 特别说明
> 以阿里云举例, `绑定其它项目的服务空间` 指的是关联其他项目的当前使用的阿里云服务空间。
1. 阿里云无法关联到腾讯云, 腾讯云也无法关联到阿里云, 但是项目可以关联,使用时会报错。
2. 如果项目已关联其他项目, 选择云服务空间, 此时关联关系会断开。
### 一个应用访问多个服务空间@multi-space
......@@ -90,8 +129,9 @@ function init(options):uniCloud
**注意**
- 云函数会自动识别自己所属的服务空间,调用本服务空间下的资源时无需初始化。
- 云函数环境(仅腾讯云支持)仅能通过init返回同账号下其他的腾讯云服务空间实例。
- 客户端环境(腾讯云阿里云均支持)可以通过init返回本账号下任意云厂商服务空间实例
- 客户端环境(腾讯云阿里云均支持)可以通过init返回本账号下任意云厂商服务空间实例
**options 参数说明**
......@@ -117,9 +157,4 @@ myCloud.uploadFile()
```
**Tips:**
- 云函数会自动识别自己所属的服务空间,无需初始化。
- 腾讯云支持在云函数内初始化本账号下的其他服务空间
uniCloud还支持跨服务空间的数据库访问,另见[文档](https://uniapp.dcloud.net.cn/uniCloud/hellodb?id=init-db)
\ No newline at end of file
......@@ -5,7 +5,8 @@
- 场景1:比如App端微信支付,需要配服务器回调地址,此时需要一个HTTP URL。
- 场景2:非uni-app开发的系统,想要连接uniCloud,读取数据,也需要通过HTTP URL方式访问。
云函数默认是只有自己的app在前端通过`uniCloud.callFunction`来调用的,不会暴露到外网。一旦URL化后,开发者需要关注业务和资源安全。
url化后需要注意以下几点
- 安全:为了保障业务安全性,开发者需在代码中做好权限控制和安全防护,避免未授权访问触发敏感操作。
- 计费:云函数开启了URL化后,如果遇到大量恶意访问,消耗云函数资源,开发者可以将云函数访问地址设置为空即可停止 HTTP 访问支持。
......
......@@ -387,9 +387,9 @@ const res = await db.collection(order, 'book').get() // 将获取的order表的
上面两种写法最终结果一致,但是第二种写法性能更好。第一种写法会先将所有数据进行关联,如果数据量很大这一步会消耗很多时间。详细示例见下方说明
**关联查询后的虚拟联表数据结构如下:**
**关联查询后的返回结果数据结构如下:**
> 通过HBuilderX提供的[JQL数据库管理](uniCloud/jql-runner.md)功能方便的查看联表查询时的虚拟联表结构
> 通过HBuilderX提供的[JQL数据库管理](uniCloud/jql-runner.md)功能方便的查看联表查询时返回数据的结构
主表某字段foreignKey指向副表时
......@@ -633,7 +633,7 @@ db.collection('order')
在前端页面调试JQL联表查询且不过滤字段时会受权限影响,导致调试比较困难。可以通过HBuilderX提供的[JQL数据库管理](uniCloud/jql-runner.md)功能方便的查看联表查询时的虚拟联表结构。
如上述查询可以直接在`JQL文件`中执行以下代码查看完整的虚拟联表字段
如上述查询可以直接在`JQL文件`中执行以下代码查看完整的返回字段
```js
db.collection('order,book').get()
......@@ -978,7 +978,7 @@ db.collection(comment, user)
**关联查询后的数据结构如下:**
> 通过HBuilderX提供的[JQL数据库管理](uniCloud/jql-runner.md)功能方便的查看联表查询时的虚拟联表结构
> 通过HBuilderX提供的[JQL数据库管理](uniCloud/jql-runner.md)功能方便的查看联表查询时返回数据的结构
主表某字段foreignKey指向副表时
......
......@@ -528,7 +528,7 @@ uniCloud支持云函数,但其实大多数场景下并不需要写云函数,
根据下表,在小程序管理后台设置request合法域名、uploadFile合法域名(如没有上传文件业务,可不设置)。下表的域名均为阿里云或腾讯云自有域名,并非DCloud所属域名。
|服务提供商 |request合法域名 |uploadFile合法域名 |download合法域名
|服务提供商 |request合法域名 |uploadFile合法域名 |download合法域名|
|:-: |:-: |:-: |:-:|
|阿里云 |api.bspapp.com |bsppub.oss-cn-shanghai.aliyuncs.com|需要从云存储下载文件的时候才需要配置,不同服务空间域名不同,可以在web控制台查看文件详情里面看到|
|腾讯云 |tcb-api.tencentcloudapi.com|cos.ap-shanghai.myqcloud.com |需要从云存储下载文件的时候才需要配置,不同服务空间域名不同,可以在web控制台查看文件详情里面看到|
......
......@@ -384,6 +384,8 @@ enum支持3种数据格式:
- 数据表查询
**这种使用方式需要搭配foreignKey来使用,请看下面示例**
一个字段的合法值域,可以是从另一个数据查询而来。也即,在enum中可以配置jql查询语句。
例如有一个角色表uni-id-roles,里面已经存在若干个角色。那么在用户表uni-id-users的role字段里,就可以在enum里写jql查询,约定用户的角色字段的值,比如是在角色表中已经存在的值。
......
......@@ -44,7 +44,7 @@ keyword: 短信,sms
1. 不能包含涉政、黄赌毒、暴力、房产、移民、贷款、代开发票等违法内容
2. 不能包含运营商禁止发送的内容
3. 不能包含侵犯第三方权益的内容(如侵犯他人商标或冒名行为)
4. 营销类短信不能违广告法
4. 营销类短信不能违广告法
5. 不能利用短信骚扰或诈骗用户
报备模板的方式:
......
# 为什么使用uni-config-center
实际开发中很多插件/云函数/公共模块需要配置文件才可以正常运行,如果每个都单独进行配置的话就会产生下面这样的目录结构
```text
cloudfunctions
├─common
│ └─user-utils // user-utils公共模块
│ ├─custom-token.js // user-utils依赖的其他文件
│ └─config.json // user-utils使用的配置文件
├─payment-config-test // payment-config-test云函数
│ └─config.json // payment-config-test使用的配置文件
└─user-config-test // 引用user-utils的云函数
```
可以看到配置文件分散在各个地方,毫无章法,维护起来也是一个大麻烦。
uni-config-center就是用了统一管理这些配置文件的,使用uni-config-center后的目录结构如下
```text
cloudfunctions
├─common
│ ├─uni-config-center
│ │ ├─payment // 插件配置目录
│ │ │ └─config.json // 插件配置文件
│ │ └─user-utils // 插件配置目录
│ │ ├─custom-token.js // 插件依赖的其他文件
│ │ └─config.json // 插件配置文件
│ └─user-utils // user-utils公共模块,此公共模块内使用user-utils插件的配置
├─payment-config-test // payment-config-test云函数,此云函数内使用payment插件的配置
└─user-config-test // 引用user-utils的云函数
```
使用uni-config-center后的优势
- 配置文件统一管理,分离插件主体和配置信息,更新插件更方便
- 支持对config.json设置schema,插件使用者在HBuilderX内编写config.json文件时会有更好的提示(后续HBuilderX会提供支持)
# 用法
在要使用uni-config-center的公共模块或云函数内引入uni-config-center依赖,请参考:[使用公共模块](https://uniapp.dcloud.net.cn/uniCloud/cf-common)
以下以在云函数`user-config-test`内使用`uni-config-center`为例,分步骤讲解如何使用
1. 从插件市场导入本插件到项目内
2. 在云函数`user-config-test`上右键选择`管理公共模块依赖`
3. 弹窗中勾选`uni-config-center`公共模块后点击`更新依赖`
4.`cloudfunctions/common/uni-config-center`目录创建存放配置的目录,在本示例中我们使用`user-utils`作为配置目录名
5. 在上一步创建的`user-utils`目录下创建配置文件`config.json`
6. 如何在代码中获取配置请参考下面的章节
至此多云函数/公共模块共享的配置就创建完成了,目录结构如下
```text
cloudfunctions
├─common
│ └─uni-config-center
│ └─user-utils // 配置目录
│ └─config.json // 配置文件
└─user-config-test // 引用user-utils的云函数
```
## 简单示例
以上述目录结构为例,在云函数`user-config-test`内获取user-utils配置目录下的配置内容,示例代码如下
```js
// user-config-test/index.js
const createConfig = require('uni-config-center')
const userUtilsConfig = createConfig({ // 获取配置实例
pluginId: 'user-utils' // common/uni-config-center下的配置目录名
})
const userUtilsConfig = userUtilsConfig.config() // 获取common/uni-config-center/user-utils/config.json的内容
exports.main = async function(event, context) {
}
```
详细接口说明请阅读下方文档。
## 获取配置实例
通过`createConfig`接口即可获取配置实例,此实例上有一些方法如:获取配置内容、拼接目录路径等
**接口形式**
```js
const createConfig = require('uni-config-center')
createConfig({
pluginId,
defaultConfig,
customMerge
})
```
**参数说明**
|参数名 |类型 |必填 |说明 |
|-- |-- |-- |-- |
|pluginId |string |是 |common/uni-config-center下的配置目录名 |
|defaultConfig |Object |否 |默认配置 |
|customMerge |Function |否 |自定义默认配置和用户配置的合并规则,不设置的情况下会对默认配置和用户配置进行深度合并 |
**代码示例**
```js
const createConfig = require('uni-config-center')
const userUtilsConfig = createConfig({
pluginId: 'user-utils', // 同common/uni-config-center下的配置目录名
defaultConfig: { // 默认配置
tokenExpiresIn: 7200,
tokenExpiresThreshold: 600,
},
customMerge: function(defaultConfig, userConfig) { // 自定义默认配置和用户配置的合并规则,不设置的情况下会对默认配置和用户配置进行深度合并
// defaudltConfig 默认配置
// userConfig 用户配置
return Object.assign(defaultConfig, userConfig)
}
})
```
## 获取配置内容
获取配置内容接口有以下几种形式,如果在createConfig时传入了`defaultConfig`,会和配置目录下的config.json合并作为完整的配置文件。
```js
// 获取配置
userUtilsConfig.config() // 获取全部配置,没有获取到配置时返回空对象
userUtilsConfig.config('tokenExpiresIn') // 传入参数名获取指定配置
userUtilsConfig.config('service.sms.codeExpiresIn') // 传入参数路径获取指定配置
userUtilsConfig.config('tokenExpiresThreshold', 600) // 获取指定配置,如果不存在则取传入的默认值
```
## 获取配置目录下的文件的绝对路径
```js
userUtilsConfig.resolve('custom-token.js') // 获取uni-config-center/user-utils/custom-token.js文件的路径
```
## 引用配置目录下的js、json文件
```js
userUtilsConfig.requireFile('custom-token.js') // 使用require方式引用uni-config-center/user-utils/custom-token.js文件。文件不存在时返回undefined,文件内有其他错误导致require失败时会抛出错误。
```
## 判断配置目录下是否存在指定文件
```js
userUtilsConfig.hasFile('custom-token.js') // 配置目录是否包含某文件,true: 文件存在,false: 文件不存在
```
\ No newline at end of file
> 从HBuilderX 2.0.3 起,uni-app、5+App、wap2app均支持UniPush
>从HBuilderX2.7.10开始,支持谷歌FCM,参考:[https://ask.dcloud.net.cn/article/37356](https://ask.dcloud.net.cn/article/37356)
> 从HBuilderX 2.0.3 起,uni-app、5+App、wap2app均支持UniPush
>从HBuilderX2.7.10开始,支持谷歌FCM,参考:[https://ask.dcloud.net.cn/article/37356](https://ask.dcloud.net.cn/article/37356)
## 概述
......@@ -14,13 +14,15 @@ uniPush解决了这个难题,开发者只需要开发一次。系统会自动
UniPush即降低了开发成本、又提高了push送达率,并且免费,是当前推送的最佳解决方案。
有了unipush,开发者不应该再使用其他push方案了。但我们发现很多开发者有误解,导致还在错误使用其他推送。
- 常见误解1:“uniPush的专业性,和专业的个推、极光等服务可相比吗?”
答:uniPush是由个推将其本来收费的vip push产品,免费提供给了DCloud的开发者。它与个推vip push的只有2个区别:1、免费;2、账户使用的是DCloud开发者账户,而无需再重新注册个推账户。个推是A股上市公司,专业性在推送领域领先。
- 常见误解2:“uniPush好麻烦,我就喜欢个推、极光这种简单sdk,不想去各个rom厂商去申请一圈”
- 常见误解1:“uniPush的专业性,和专业的个推、极光等服务可相比吗?”
答:uniPush是由个推将其本来收费的vip push产品,免费提供给了DCloud的开发者。它与个推vip push的只有2个区别:
+ 免费
+ 账户使用的是DCloud开发者账户,而无需再重新注册个推账户。个推是A股上市公司,专业性在推送领域领先。
- 常见误解2:“uniPush好麻烦,我就喜欢个推、极光这种简单sdk,不想去各个rom厂商去申请一圈”
答:uniPush不建立在申请手机厂商授权的基础上,如果你不申请那些,使用起来和用普通的个推是一样的。但是要特别注意,推送行业的现状就是:**不集成rom厂商的推送,就无法在App离线时发送push。**。按照普通个推模式使用,后果就是在华为、小米、OPPO、VIVO、魅族上发不了离线消息。
- 常见误解3:“uniPush的送达率还是不够,是否可以付费来提升送达率,个推是有付费提升送达率的方法的”
- 常见误解3:“uniPush的送达率还是不够,是否可以付费来提升送达率,个推是有付费提升送达率的方法的”
答:前文已经说了。个推的付费提升送达率的产品就是vip push,而uniPush就是个推的vip Push。DCloud通过谈判免费给DCloud的开发者使用了。
- 常见误解4:开通uniPush要实名认证,还得传身份证,开通普通个推不用这么麻烦。
- 常见误解4:开通uniPush要实名认证,还得传身份证,开通普通个推不用这么麻烦。
答:此问题之前曾存在,后来已经处理,保持和个推需要的身份信息相同,不再需要身份证。
UniPush推送服务由“个推”专为DCloud订制提供技术支持,因此在服务端的集成与“个推·消息推送”完全一致。对于之前使用个推的开发者,可以平滑的迁移到uniPush方案上。
......@@ -35,22 +37,22 @@ UniPush推送服务由“个推”专为DCloud订制提供技术支持,因此
### 推送消息类型
通常推送消息分以下两种类型:
- 通知栏消息(推送通知)
UniPush推送服务定义好的推送样式、后续动作的推送方式,客户端接收到后显示在系统通知栏,用户点击通知栏消息启动APP(激活到前台)。
- 通知栏消息(推送通知)
UniPush推送服务定义好的推送样式、后续动作的推送方式,客户端接收到后显示在系统通知栏,用户点击通知栏消息启动APP(激活到前台)。
- 透传消息
即自定义消息,UniPush推送服务只负责消息传递,不做任何处理,客户端在接收到透传消息后需要自己去处理消息的展示方式或后续动作。
**UniPush推送服务对透传消息的数据符合以下格式时做了特殊处理,会将如下格式的透传消息,直接在通知栏中展示通知。注意:1、只适用于安卓,ios仍需要开发者手动在receive透传回调中创建通知;2、下列格式的透传消息,消息到达时不会进入receive回调,只有点击消息激活APP触发"click"事件。**
- 透传消息
即自定义消息,UniPush推送服务只负责消息传递,不做任何处理,客户端在接收到透传消息后需要自己去处理消息的展示方式或后续动作。
**UniPush推送服务对透传消息的数据符合以下格式时做了特殊处理,会将如下格式的透传消息,直接在通知栏中展示通知。注意:1、只适用于安卓,ios仍需要开发者手动在receive透传回调中创建通知;2、下列格式的透传消息,消息到达时不会进入receive回调,只有点击消息激活APP触发"click"事件。**
```json
{"title": "xxx","content": "xxx","payload": "xxx"}
```
## 第一步:开通UniPush推送服务
## 第一步:开通UniPush推送服务
[点此查看如何开通UniPush推送服务](https://ask.dcloud.net.cn/article/35716)
### Android平台支持厂商推送通道
** 注意:开通UniPush后,需在后台配置“厂商推送设置”,配置好厂商参数后请一定要提交云打包,并且使用“自有证书”打签名包;将云打包后的安装包安装到手机上,再获取cid 进行离线厂商推送测试,不可使用基座方式获取的cid进行离线厂商推送测试。 **
### Android平台支持厂商推送通道
**注意:开通UniPush后,需在后台配置“厂商推送设置”,配置好厂商参数后请一定要提交云打包,并且使用“自有证书”打签名包;将云打包后的安装包安装到手机上,再获取cid 进行离线厂商推送测试,不可使用基座方式获取的cid进行离线厂商推送测试。**
![](https://www.dcloud.io/docs/a/unipush/s0.png)
获取手机厂商推送设置信息请参考:[厂商推送应用创建配置流程](https://www.dcloud.io/docs/a/unipush/manufacturer.pdf)
......@@ -58,16 +60,19 @@ UniPush推送服务定义好的推送样式、后续动作的推送方式,客
iOS平台需要使用到苹果的APNS,务必在后台正确配置苹果推送证书,参考:[iOS推送证书配置](https://ask.dcloud.net.cn/article/35716#ios)
## 第二步:服务端下发推送消息
<a id="intent"></a>
<a id="intent"/>
使用厂商推送下发推送消息必须设置intent,该数据格式是Android原生Intent对象序列化由来。具体可参考[详情](https://blog.csdn.net/u011068702/article/details/51406572)。并且intent须符合以下格式,此格式时在个推定义额基础上二次封装,所以必须以此格式为准。不按此格式设置intent可能出现用户点击推送消息无法启动APP的问题。
intent数据格式如下:
```
intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;component=io.dcloud.HBuilder/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=测试标题;S.content=测试内容;S.payload=test;end
```
**component=io.dcloud.HBuilder/io.dcloud.PandoraEntry 其中io.dcloud.HBuilder为APP包名,需要替换为自己APP的包名;**
S.title=的值为推送消息标题,对应5+ API中[PushMessage](https://www.html5plus.org/doc/zh_cn/push.html#plus.push.PushMessage)对象的title属性值;
S.content=的值为推送消息内容,对应5+ API中[PushMessage](https://www.html5plus.org/doc/zh_cn/push.html#plus.push.PushMessage)对象的content属性值;
S.payload=的值为推送消息的数据,对应5+ API中[PushMessage](https://www.html5plus.org/doc/zh_cn/push.html#plus.push.PushMessage)对象的payload属性值;
**component=io.dcloud.HBuilder/io.dcloud.PandoraEntry 其中io.dcloud.HBuilder为APP包名,需要替换为自己APP的包名;**
S.title=的值为推送消息标题,对应5+ API中[PushMessage](https://www.html5plus.org/doc/zh_cn/push.html#plus.push.PushMessage)对象的title属性值;
S.content=的值为推送消息内容,对应5+ API中[PushMessage](https://www.html5plus.org/doc/zh_cn/push.html#plus.push.PushMessage)对象的content属性值;
S.payload=的值为推送消息的数据,对应5+ API中[PushMessage](https://www.html5plus.org/doc/zh_cn/push.html#plus.push.PushMessage)对象的payload属性值;
**launchFlags=0x14000000字段,解决接收多条通知后点击可能无法触发click事件的问题**
注意事项:
......@@ -75,7 +80,7 @@ S.payload=的值为推送消息的数据,对应5+ API中[PushMessage](https://
- intent是为了兼容Android平台的数据,但为了保持兼容性,建议iOS平台也配置此数据
- action=android.intent.action.oppopush为固定的数据,是兼容oppo设备的离线推送功能,不需要修改
- component=io.dcloud.HBuilder/io.dcloud.PandoraEntry中的io.dcloud.HBuilder为应用的包名,与App云端打包界面设置的Android包名一致
[attach]48942[/attach]
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/push/packagename.png)
### 通过开发者中心后台Web页面发送Push消息
......@@ -93,14 +98,13 @@ S.payload=的值为推送消息的数据,对应5+ API中[PushMessage](https://
#### 如果使用传统服务器开发
参考“个推·消息推送”的服务端快速集成文档[http://docs.getui.com/](http://docs.getui.com/)
[attach]69845[/attach]
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/push/unipush-api-getui.png)
**通过服务端接口下发推送消息,需要封装个推侧Rest-V2接口。应用在前台,透传内容若使用Dcloud侧要求的格式,则安卓客户端不进透传receive回调,自动创建通知栏通知;IOS开发者则需要在客户端receive透传回调中自己处理创建本地通知;应用在后台使用厂商通道需配置push_channel中的相关参数才可生效。**
以下是Rest-V2厂商推送示例:
```
``` json
{
    "request_id":"请填写10到32位的id",
    "audience": {
......@@ -144,8 +148,7 @@ S.payload=的值为推送消息的数据,对应5+ API中[PushMessage](https://
```
以下是Java-sdk封装Rest-V2厂商推送示例:
```
``` java
public class push2 {
public static void main(String[] args) {
GtApiConfiguration apiConfiguration = new GtApiConfiguration();
......@@ -232,7 +235,8 @@ public class push2 {
**注意:把$intent变量赋值字符串中的io.dcloud.HBuilder换成自己应用的包名**
<a id="server"></a>
<a id="server"/>
完整服务端厂商推送教程参考:
https://docs.getui.com/getui/server/rest_v2/common_args/
......@@ -245,13 +249,18 @@ UniPush推送服务已经封装好iOS&Android平台的原生集成工作,开
- uni-app应用中使用UniPush推送服务参考[https://ask.dcloud.net.cn/article/35726](https://ask.dcloud.net.cn/article/35726)
<a id="badge"/>
### 应用桌面图标的角标
#### Android平台
不同ROM接收推送消息对桌面图标的角标处理逻辑存在差别
- 小米手机:角标自动加1 (MIUI11 以下) 另:高版本MIUI 设置角标会以通知的形态发送
- 华为手机:可以设置,走厂家通道离线推送可在服务端设置。参考可插件链接:[https://ext.dcloud.net.cn/plugin?id=1680](https://ext.dcloud.net.cn/plugin?id=1680)
- vivo手机:不会自动加1,需调用5+ API [plus.runtime.setBadgeNumber](https://www.html5plus.org/doc/zh_cn/runtime.html#plus.runtime.setBadgeNumber)动态设置角标数字
- oppo手机:角标自动展示,具体形态与rom相关,可能是红点或数字。(需要打开角标权限)
### 应用桌面图标的角标
#### Android平台
不同ROM接收推送消息对桌面图标的角标处理逻辑存在差别
- 小米手机:
角标自动加1 (MIUI11 以下),另:高版本MIUI 设置角标会以通知的形态发送
- 华为手机:
可以设置,走厂家通道离线推送可在服务端设置。参考可插件链接:[https://ext.dcloud.net.cn/plugin?id=1680](https://ext.dcloud.net.cn/plugin?id=1680)
- vivo手机:
不会自动加1,需调用5+ API [plus.runtime.setBadgeNumber](https://www.html5plus.org/doc/zh_cn/runtime.html#plus.runtime.setBadgeNumber)动态设置角标数字
- oppo手机:
角标自动展示,具体形态与rom相关,可能是红点或数字。(需要打开角标权限)
#### iOS平台
根据接收到的推送消息处理桌面图标的角标,在uniPush后台的“iOS配置”项中可配置badge参数对角标进行设置,可取值:
......@@ -263,15 +272,15 @@ UniPush推送服务已经封装好iOS&Android平台的原生集成工作,开
## 注意事项
### 推送通道选择逻辑
- Android平台
**APP在线(个推推送通道可用)**
推送通知和透传消息都使用个推的推送通道下发推送消息。
**APP离线(个推推送通道不可用)**
- Android平台
**APP在线(个推推送通道可用)**
推送通知和透传消息都使用个推的推送通道下发推送消息。
**APP离线(个推推送通道不可用)**
推送通知,使用个推离线推送通道,离线消息会存储在消息离线库,离线时间内APP在线后下发推送消息。
透传消息,如果符合厂商推送的厂商手机(配置了手机厂商推送参数并且在对应厂商的手机上),则使用厂商推送通道下发推送消息;否则使用个推的离线推送通道,离线消息会存储在消息离线库,离线时间内APP在线后下发推送消息。
- iOS平台
推送通知,uniPush后台管理界面中不支持下发此类型,个推提供的服务端API支持下发推送通知(设置APN参数则通过苹果的APNS通道,否则使用个推通道)。
- iOS平台
推送通知,uniPush后台管理界面中不支持下发此类型,个推提供的服务端API支持下发推送通知(设置APN参数则通过苹果的APNS通道,否则使用个推通道)。
透传消息,设置APN参数则通过苹果的APNS通道下发推送消息,没有设置APN参数则使用个推的推送通道下发。
### Android平台厂商通道
......@@ -279,51 +288,49 @@ UniPush推送服务已经封装好iOS&Android平台的原生集成工作,开
在华为手机上必须安装“华为移动服务”才能使用华为的厂商推送通道,首先确保手机上已经安装“华为移动服务”应用。
如果在华为手机应用退出后无法接收到推送消息,需要确保:
1机型版本要求:华为rom且华为rom版本大于等于 emui4.1, 华为移动服务(可在应用列表或华为应用市场中查看)版本大于等于 2.5.2。
2需要提交云打包,打自有证书-签名包(包名要确认与华为平台一致)。
3华为平台【我的项目】-【项目设置】-【常规】中填写“SHA256证书指纹”,点右侧对勾保存证书指纹。
4emui10的华为手机,检查手机通知权限设置,将【营销通知】的权限也打开,不要默认静默,静默的话是需要下拉通知栏才能看到。
5手机通知栏消息是否有存满,清除已存的通知栏消息看下新的消息是否能展示。
6清除华为移动服务(HMS Core)(apk(手机设置--应用--应用管理--点击显示系统进程--搜索(华为移动服务)--存储--清空缓存))的缓存
1. 机型版本要求:华为rom且华为rom版本大于等于 emui4.1, 华为移动服务(可在应用列表或华为应用市场中查看)版本大于等于 2.5.2。
2. 需要提交云打包,打自有证书-签名包(包名要确认与华为平台一致)。
3. 华为平台【我的项目】-【项目设置】-【常规】中填写“SHA256证书指纹”,点右侧对勾保存证书指纹。
4. emui10的华为手机,检查手机通知权限设置,将【营销通知】的权限也打开,不要默认静默,静默的话是需要下拉通知栏才能看到。
5. 手机通知栏消息是否有存满,清除已存的通知栏消息看下新的消息是否能展示。
6. 清除华为移动服务(HMS Core)(apk(手机设置--应用--应用管理--点击显示系统进程--搜索(华为移动服务)--存储--清空缓存))的缓存
HBuilderX3.0.7 之后,华为除了配置原有的厂商信息之外,需要新增配置 agconnect-services.json文件。
该文件,需要从华为开发者后台--项目设置界面下载
[attach]67632[/attach]
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/push/huawei-apconnect-services.png)
#### VIVO厂商通道
**需要在VIVO应用商店上线才能申请VIVO的厂商推送**
注意事项:
1vivo【运营消息】,一个设备一天只能收到5条离线消息
2vivo要求:通知文案中不能带 “包含测试、test字符”、“纯数字”、“纯表情”、“符号”或者“符号+数 字”、“表情+数字”、“表情+符号” 。
31个自然日内相同文案的运营消息给同个设备发,vivo会在客户端做去重处理,导致消息不展示
4支持vivo推送功能HBuilderX最低版2.1.0及以上。
1. vivo【运营消息】,一个设备一天只能收到5条离线消息
2. vivo要求:通知文案中不能带 “包含测试、test字符”、“纯数字”、“纯表情”、“符号”或者“符号+数 字”、“表情+数字”、“表情+符号” 。
3. 1个自然日内相同文案的运营消息给同个设备发,vivo会在客户端做去重处理,导致消息不展示
4. 支持vivo推送功能HBuilderX最低版2.1.0及以上。
具体请参考图中数据
[attach]41669[/attach]
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/push/vivo-datas.png)
#### OPPO厂商通道
**需要在OPPO应用商店上线才能申请OPPO的厂商推送**
并且有以下要求:
1、机型系统要求:oppo colorOS rom且版本号大于等于3.1
2、检查手机通知权限是否打开,oppo是默认关闭的,将通知权限下的【Default】通道权限也打开。
3、手机系统时间是否正常
1. 机型系统要求:oppo colorOS rom且版本号大于等于3.1
2. 检查手机通知权限是否打开,oppo是默认关闭的,将通知权限下的【Default】通道权限也打开。
3. 手机系统时间是否正常
#### 小米厂商通道
1机型版本要求:小米rom且小米服务框架(包名:com.xiaomi.xmsf)版本号⼤于等于 105
2检查手机通知权限设置,小米有不重要通知功能,部分消息可能会存在通知栏不重要通知里
1. 机型版本要求:小米rom且小米服务框架(包名:com.xiaomi.xmsf)版本号⼤于等于 105
2. 检查手机通知权限设置,小米有不重要通知功能,部分消息可能会存在通知栏不重要通知里
#### 魅族厂商通道
1、机型版本要求:魅族rom且魅族rom版本⼤于等于5.x
2、检查消息是否存入了魅族手机右上角【魅族消息盒子】中
3、清除缓存:魅族手机在设置 ---> 应用管理 ---> 所有应用 ---> 推送服务 ,点击里面的清除数据,然后再重新安装一下应用。
1. 机型版本要求:魅族rom且魅族rom版本⼤于等于5.x
2. 检查消息是否存入了魅族手机右上角【魅族消息盒子】中
3. 清除缓存:魅族手机在设置 ---> 应用管理 ---> 所有应用 ---> 推送服务 ,点击里面的清除数据,然后再重新安装一下应用。
#### 谷歌FCM通道
......@@ -332,8 +339,10 @@ HBuilderX3.0.7 之后,华为除了配置原有的厂商信息之外,需要
#### 其它厂商通道
如果应用在线可以接收到推送消息,离线时使用厂商通道无法接收到推送消息,可参考**UniPush厂商通道常见问题[https://ask.dcloud.net.cn/article/36611](https://ask.dcloud.net.cn/article/36611)**
** 最后也可以登录[个推官网](https://www.getui.com/),或使用微信扫描下面二维码,进行技术咨询**
[attach]69315[/attach]
**最后也可以登录[个推官网](https://www.getui.com/),或使用微信扫描下面二维码,进行技术咨询**
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/push/getui-service.jpg)
## 其他相关资源
......@@ -343,13 +352,13 @@ HBuilderX3.0.7 之后,华为除了配置原有的厂商信息之外,需要
- 如何自定义推送通知的图标:[https://ask.dcloud.net.cn/article/35537](https://ask.dcloud.net.cn/article/35537)
## FAQ
Q:5+app和wap2app需要uniPush怎么办?
- Q:5+app和wap2app需要uniPush怎么办?
A:HBuilderX 2.0.3起,5+app和wap2app也支持了uniPush。
5+app和wap2app升级uniPush不需要改动app前端代码,只需要在HBuilderX中打开manifest.json的“SDK配置”页,在“推送”下勾选“DCloud UniPush”,并点击“配置”,在后台开通unipush服务,配置好厂商推送参数重新提交云端打包即可。后端服务器需要参考第二步对接个推推送服务。
Q:离线打包如何配置?
- Q:离线打包如何配置?
A:[Android平台App离线打包-Push](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/androidModuleConfig/push?id=unipush)
[iOS平台App离线打包-Push](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/iOSModuleConfig/push?id=unipush)
Q:iOS平台如何实现应用启动后不立即弹出“发送通知”系统授权框
- Q:iOS平台如何实现应用启动后不立即弹出“发送通知”系统授权框?
A:参考:[https://ask.dcloud.net.cn/article/36955](https://ask.dcloud.net.cn/article/36955#push)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册