提交 4f4f2605 编写于 作者: Q qiang

Merge branch 'dev' into alpha

# Conflicts:
#	packages/uni-app-plus/dist/index.js
......@@ -27,6 +27,7 @@
* [混合开发](hybrid.md)
* [uni小程序sdk](https://nativesupport.dcloud.net.cn/README)
* 运营服务
* [App升级中心](uniCloud/upgrade-center.md)
* [uni一键登录](univerify.md)
* [统一推送uniPush](unipush.md)
* [uni统计](uni-stat.md)
......@@ -80,7 +81,7 @@
<img src="https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/759713d0-4f2d-11eb-a16f-5b3e54966275.png" width="20" height="20"/>
<div class="contact-smg">
<div>官方QQ交流群</div>
<div>群24:672494800 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=7ntnubNkRwi2DlXS02C4OEFfm2KbvnBu&jump_from=webapi">点此加入</a></div>
<div>群27:811363410 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=noDvG6kfZgzXh-Wbp5MRhNutYCojx08G&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -89,10 +90,10 @@
<div>群30:371046920(2000人已满)</div>
<div>群29:202965481(2000人已满)</div>
<div>群28:166188776(2000人已满)</div>
<div>群27:811363410(2000人已满)</div>
<!-- <div>群27:811363410(2000人已满)</div> -->
<div>群26:147867597(2000人已满)</div>
<div>群25:165297000(2000人已满)</div>
<!-- <div>群24:672494800(2000人已满)</div> -->
<div>群24:672494800(2000人已满)</div>
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<div>群21:717019120(2000人已满)</div>
......
......@@ -5,6 +5,7 @@
* [uni.arrayBufferToBase64](api/arrayBufferToBase64?id=arraybuffertobase64)
* [生命周期](api/lifecycle.md)
* [应用级事件](api/application.md)
* [拦截器](api/interceptor.md)
* 网络
* [发起请求](api/request/request.md)
* [上传、下载](api/request/network-file.md)
......@@ -123,6 +124,7 @@
* [支付](api/plugins/payment.md)
* [推送](api/plugins/push.md)
* [语音](api/plugins/voice.md)
* [一键生成iOS通用链接](api/plugins/universal-links.md)
* [uniCloud](api/uniCloud.md)
* 平台扩展
* [App原生插件](api/extend/native-plugin.md)
......@@ -179,7 +181,7 @@
<img src="https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/759713d0-4f2d-11eb-a16f-5b3e54966275.png" width="20" height="20"/>
<div class="contact-smg">
<div>官方QQ交流群</div>
<div>群24:672494800 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=7ntnubNkRwi2DlXS02C4OEFfm2KbvnBu&jump_from=webapi">点此加入</a></div>
<div>群27:811363410 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=noDvG6kfZgzXh-Wbp5MRhNutYCojx08G&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -188,10 +190,10 @@
<div>群30:371046920(2000人已满)</div>
<div>群29:202965481(2000人已满)</div>
<div>群28:166188776(2000人已满)</div>
<div>群27:811363410(2000人已满)</div>
<!-- <div>群27:811363410(2000人已满)</div> -->
<div>群26:147867597(2000人已满)</div>
<div>群25:165297000(2000人已满)</div>
<!-- <div>群24:672494800(2000人已满)</div> -->
<div>群24:672494800(2000人已满)</div>
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<div>群21:717019120(2000人已满)</div>
......
......@@ -23,7 +23,7 @@
* App平台:[https://uniad.dcloud.net.cn/](https://uniad.dcloud.net.cn/)
2. 申请广告位id
在各位后台申请广告位id
3. App端打包后生效,打包时必须选择要集成的广告SDK(目前仅支持快手联盟)。
3. App端打包后生效,打包时必须选择要集成的广告SDK(目前仅支持快手内容联盟)。
### 语法
......
......@@ -50,92 +50,75 @@ uni.createFullScreenVideoAd(Object)
示例代码
```
```html
<template>
<view>
<view class="uni-padding-wrap uni-common-mt">
<button :loading="loading" :disabled="loading" type="primary" class="btn" @click="showAd">显示广告</button>
</view>
</view>
<view>
<button :loading="loading" :disabled="loading" type="primary" @click="showFullScreenVideoAd">显示广告</button>
</view>
</template>
<script>
export default {
data() {
return {
title: '全屏视频广告',
loading: false,
loadError: false
}
},
onReady() {
// #ifdef APP-PLUS
// HBuilderX标准基座真机运行测试全屏视频广告位标识(adpid)为:1507000611
// adpid: 1507000611 仅用于测试,发布时需要改为广告后台(https://uniad.dcloud.net.cn/)申请的 adpid
// 广告后台申请的广告位(adpid)需要自定义基座/云打包/本地打包后生效
this.adOption = {
adpid: '1507000611'
};
// #endif
this.createAd();
},
methods: {
createAd() {
var _ad = this._ad = uni.createFullScreenVideoAd(this.adOption);
_ad.onLoad(() => {
this.loading = false;
this.loadError = false;
_ad.show();
console.log('onLoad event')
});
_ad.onClose((res) => {
// 用户点击了【关闭广告】按钮
if (res && res.isEnded) {
// 正常播放结束
console.log("onClose " + res.isEnded);
} else {
// 播放中途退出
console.log("onClose " + res.isEnded);
}
setTimeout(() => {
uni.showToast({
title: "全屏视频" + (res.isEnded ? "成功" : "未") + "播放完毕",
duration: 10000,
position: 'bottom'
})
}, 500)
});
_ad.onError((err) => {
this.loading = false;
if (err.code) {
this.loadError = true;
}
console.log('onError event', err)
uni.showToast({
title: err.errMsg,
position: 'bottom'
})
});
},
showAd() {
this.loading = true;
this._ad.load();
}
}
}
export default {
data() {
return {
title: '全屏视频广告',
loading: false
}
},
onReady() {
// HBuilderX标准基座真机运行测试全屏视频广告位标识(adpid)为:1507000611
// adpid: 1507000611 仅用于测试,发布时需要改为广告后台(https://uniad.dcloud.net.cn/)申请的 adpid
// 广告后台申请的广告位(adpid)需要自定义基座/云打包/本地打包后生效
this.adOption = {
adpid: '1507000611'
};
// 创建广告实例
this.createFullScreenVideoAd();
},
methods: {
createFullScreenVideoAd() {
var fullScreenVideoAd = this.fullScreenVideoAd = uni.createFullScreenVideoAd(this.adOption);
fullScreenVideoAd.onLoad(() => {
// 广告数据加载成功
this.loading = false;
console.log("onLoad");
});
fullScreenVideoAd.onClose((e) => {
// 用户点击了关闭或返回键(仅Android有返回键)
console.log("onClose " + e.isEnded);
});
fullScreenVideoAd.onError((err) => {
console.log("onError", JSON.stringify(err));
// 广告数据加载失败
this.loading = false;
uni.showToast({
title: `${err.code} : ${err.errMsg}`
})
});
},
showFullScreenVideoAd() {
// 调用 fullScreenVideoAd.show(),如果数据正在加载中不会显示广告,加载成功后才显示
// 在数据没有加载成功时,需要防止用户频繁点击显示广告
if (this.loading == true) {
return
}
this.loading = true;
this.fullScreenVideoAd.show().then(() => {
this.loading = false;
}).catch((err) => {
console.log(err.message);
this.loading = false;
uni.showToast({
title: `${err.code} : ${err.errMsg}`
})
});
}
},
onUnload() {
this.fullScreenVideoAd.destroy()
}
}
</script>
<style>
.btn {
margin-bottom: 20px;
}
.ad-tips {
color: #999;
padding: 30px 0;
text-align: center;
}
</style>
```
### 插屏广告
插屏广告组件。插屏广告组件是一个原生组件,层级比普通组件高。插屏广告组件每次创建都会返回一个全新的实例,默认是隐藏的,需要调用 InterstitialAd.show() 将其显示。
插屏广告组件是由客户端原生的图片、文本、视频控件组成的;插屏广告与信息流或横幅广告相比展现尺寸更大,同样能够满足您对大量曝光和用户转化的需求。
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-a90b5f95-90ba-4d30-a6a7-cd4d057327db/5dc1ce6b-b786-4175-aec5-dd2ab4a5e34c.png)
**平台差异说明**
|App|H5|微信小程序|支付宝小程序|百度小程序|字节跳动小程序|QQ小程序|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|x|x|√|x|x|x|x|
uni.createInterstitialAd(Object object)
|App 3.1.10+|x|√|x|x|x|√|
|属性|类型|必填|说明|
|:-:|:-:|:-:|:-:|
|adUnitId|string|是|广告单元 id,微信小程序2.6.0+|
- app端的广告源由腾讯优量汇、头条穿山甲、快手等广告联盟提供,DCloud负责聚合
- 小程序端的广告由小程序平台提供
**开通配置广告**
#### 方法
开通广告步骤:
1. 开通广告
需在广告平台后台操作:
* App平台:[https://uniad.dcloud.net.cn/](https://uniad.dcloud.net.cn/)
* 小程序平台:在各自的小程序管理后台操作。
2. 申请广告位id
在各位后台申请广告位id
3. App端打包后生效,打包时必须选择要集成的广告SDK(优量汇、穿山甲)。
### 语法
`uni.createInterstitialAd(options)`
### 参数说明
`options` 为 object 类型,属性如下:
|属性名 |类型 |必填 |描述 |最低支持版本 |
|:-:|:-:|:-:|:-:|:-:|
|adpid |string | 是|广告位 id |App 3.1.10+|
|adUnitId |string | 是|广告位 id |微信小程序2.6.0+, QQ0.1.26+|
HBuilder 基座的测试广告位 `adpid``1111111113`
### 广告创建
插屏广告组件默认是隐藏的,因此可以提前创建,以提前初始化组件。开发者可以在页面的 onReady 事件回调中创建广告实例,并在该页面的生命周期内重复调用该广告实例。
### 显示/隐藏
插屏广告组件默认是隐藏的,开发者需要调用 InterstitialAd.show() 进行显示。如果广告拉取失败或触发频率限制,InterstitialAd.show() 方法会返回一个rejected Promise,开发者可自行监听错误信息
```js
interstitialAd.show().catch((err) => {
console.error(err)
})
```
用户可以主动关闭插屏广告。开发者不可控制插屏广告组件的隐藏。
### 监听用户关闭广告
如果广告被关闭,通过 InterstitialAd.onClose() 注册的回调函数会执行,回调函数没有参数传递。
```js
interstitialAd.onClose(res => {
console.log('插屏 广告关闭')
})
```
示例代码
```html
<template>
<view>
<view>
<button :loading="loading" :disabled="loading" type="primary" @click="showInterstitialAd">显示广告</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: '插屏广告',
loading: false
}
},
onReady() {
this.adOption = {
adpid: '1111111113' // HBuilder基座的测试广告位
};
// 创建广告实例
this.createInterstitialAd();
},
methods: {
createInterstitialAd() {
var interstitialAd = this.interstitialAd = uni.createInterstitialAd(this.adOption);
interstitialAd.onLoad(() => {
this.loading = false;
console.log("插屏 广告加载成功");
});
interstitialAd.onClose(() => {
// 用户点击了关闭或返回键(仅Android有返回键)
console.log("插屏 广告关闭");
});
interstitialAd.onError((err) => {
this.loading = false;
console.log("插屏 广告加载失败");
});
// 广告实例创建成功后默认会执行一次 load,加载广告数据
// 如果界面有 "显示广告" 按钮,需要先禁用掉,防止用户点击,等待广告数据加载成功后在放开
this.loading = true;
},
showInterstitialAd() {
// 调用 interstitialAd.show(),如果数据正在加载中不会显示广告,加载成功后才显示
// 在数据没有加载成功时,需要防止用户频繁点击显示广告
if (this.loading == true) {
return
}
this.loading = true;
this.interstitialAd.show().then(() => {
this.loading = false;
});
}
},
onUnload() {
// 页面关闭后销毁实例
this.interstitialAd.destroy()
}
}
</script>
```
`Promise InterstitialAd.show()`
显示插屏广告。
#### 方法
`Promise InterstitialAd.load()`
加载插屏广告。
`Promise InterstitialAd.show()`
显示插屏广告。
`InterstitialAd.destroy()`
销毁插屏广告实例。
......@@ -53,3 +175,8 @@ uni.createInterstitialAd(Object object)
`InterstitialAd.offClose(function callback)`
取消监听插屏广告关闭事件
### 注意事项
在插屏广告展示过程中如果快速切换页面,可能会出现插屏广告展示在非调用页面的情况,如有需要请在页面切换完成后进行插屏广告展示。
......@@ -124,28 +124,61 @@ options 为 object 类型,属性如下:
推荐使用此方案
```html
<template>
<view>
<button type="primary" class="btn" @click="showRewardedVideoAd">显示激励视频广告</button>
<button type="primary" class="btn" @click="showFullScreenVideoAd">显示全屏视频广告</button>
</view>
</template>
<script>
import AD from "ad.js"
import AD from "../ad.js"
export default {
data() {
return {
title: '激励视频广告'
title: '视频广告'
}
},
onReady() {
// HBuilderX标准基座真机运行测试激励视频广告位标识(adpid)为:1507000689
// adpid: 1507000689 仅用于测试,发布时需要改为广告后台(https://uniad.dcloud.net.cn/)申请的 adpid
// 广告后台申请的广告位(adpid)需要自定义基座/云打包/本地打包后生效
this._adpid = 1507000689
// 可选预载广告数据
// AD.load({
// adpid: 1507000689,
// adType: "RewardedVideo"
// });
// 可选预加载数据, 减少加载等待时间,调用此 API 不会显示loading,不影响业务
// AD.load(this._adpid)
// AD.load({
// adpid: 1507000611,
// adType: "FullScreenVideo"
// });
},
methods: {
showAd() {
// 调用后默认显示Loading
AD.show(this._adpid, (res) => {
showRewardedVideoAd() {
// 调用后会显示 loading 界面
AD.show({
adpid: 1507000689, // HBuilder 基座测试广告位
adType: "RewardedVideo"
}, (res) => {
// 用户点击了【关闭广告】按钮
if (res && res.isEnded) {
// 正常播放结束
console.log("onClose " + res.isEnded);
} else {
// 播放中途退出
console.log("onClose " + res.isEnded);
}
}, (err) => {
// 广告加载错误
console.log(err)
})
},
showFullScreenVideoAd() {
// 调用后会显示 loading 界面
AD.show({
adpid: 1507000611, // HBuilder 基座测试广告位
adType: "FullScreenVideo"
}, (res) => {
// 用户点击了【关闭广告】按钮
if (res && res.isEnded) {
// 正常播放结束
......@@ -155,32 +188,48 @@ options 为 object 类型,属性如下:
console.log("onClose " + res.isEnded);
}
}, (err) => {
// 广告无法显示,输出错误信息
console.log(err) // {code: code, errMsg: message}
// 广告加载错误
console.log(err)
})
}
}
}
</script>
```
```js
// ad.js
const ADType = {
RewardedVideo: "RewardedVideo",
FullScreenVideo: "FullScreenVideo"
}
class AdHelper {
constructor() {
this._ads = {}
}
load(adpid, onload, onerror) {
load(options, onload, onerror) {
let ops = this._fixOldOptions(options)
let {
adpid
} = ops
if (!adpid || this.isBusy(adpid)) {
return
}
this.get(adpid).load(onload, onerror)
this.get(ops).load(onload, onerror)
}
show(adpid, onsuccess, onfail) {
show(options, onsuccess, onfail) {
let ops = this._fixOldOptions(options)
let {
adpid
} = ops
if (!adpid) {
return
}
......@@ -189,7 +238,7 @@ class AdHelper {
mask: true
})
var ad = this.get(adpid)
var ad = this.get(ops)
ad.load(() => {
uni.hideLoading()
......@@ -206,23 +255,37 @@ class AdHelper {
return (this._ads[adpid] && this._ads[adpid].isLoading)
}
get(adpid) {
get(options) {
const {
adpid
} = options
if (!this._ads[adpid]) {
this._ads[adpid] = new RewardedVideo({
adpid: adpid
})
this._ads[adpid] = this._createAdInstance(options)
}
return this._ads[adpid]
}
}
const eventNames = [
'load',
'close',
'verify',
'error'
]
_createAdInstance(options) {
const adType = options.adType || ADType.RewardedVideo
delete options.adType
let ad = null;
if (adType === ADType.RewardedVideo) {
ad = new RewardedVideo(options)
} else if (adType === ADType.FullScreenVideo) {
ad = new FullScreenVideo(options)
}
return ad
}
_fixOldOptions(options) {
return (typeof options === "string") ? {
adpid: options
} : options
}
}
const EXPIRED_TIME = 1000 * 60 * 30
const ProviderType = {
......@@ -232,8 +295,8 @@ const ProviderType = {
const RETRY_COUNT = 1
class RewardedVideo {
constructor(options = {}) {
class AdBase {
constructor(adInstance, options = {}) {
this._isLoad = false
this._isLoading = false
this._lastLoadTime = 0
......@@ -244,22 +307,22 @@ class RewardedVideo {
this._closeCallback = null
this._errorCallback = null
const rewardAd = this._rewardAd = plus.ad.createRewardedVideoAd(options)
rewardAd.onLoad((e) => {
const ad = this._ad = adInstance
ad.onLoad((e) => {
this._isLoading = false
this._isLoad = true
this._lastLoadTime = Date.now()
this.onLoad()
})
rewardAd.onClose((e) => {
ad.onClose((e) => {
this._isLoad = false
this.onClose(e)
})
rewardAd.onVerify((e) => {
ad.onVerify((e) => {
// e.isValid
})
rewardAd.onError(({
ad.onError(({
code,
message
}) => {
......@@ -294,7 +357,7 @@ class RewardedVideo {
}
getProvider() {
return this._rewardAd.getProvider()
return this._ad.getProvider()
}
load(onload, onerror) {
......@@ -333,7 +396,7 @@ class RewardedVideo {
return
}
this._rewardAd.show()
this._ad.show()
}
onLoad(e) {
......@@ -357,14 +420,26 @@ class RewardedVideo {
}
destroy() {
this._rewardAd.destroy()
this._ad.destroy()
}
_loadAd() {
this._isLoad = false
this._isLoading = true
this._lastError = null
this._rewardAd.load()
this._ad.load()
}
}
class RewardedVideo extends AdBase {
constructor(options = {}) {
super(plus.ad.createRewardedVideoAd(options), options)
}
}
class FullScreenVideo extends AdBase {
constructor(options = {}) {
super(plus.ad.createFullScreenVideoAd(options), options)
}
}
......
### uni.addInterceptor(STRING, OBJECT)
添加拦截器
**STRING 参数说明**
需要拦截的`api`名称,如:`uni.addInterceptor('request', OBJECT)` ,将拦截 `uni.request()`
**OBJECT 参数说明**
|参数名 |类型 |必填 |默认值 |说明 |平台差异说明 |
|:- |:- |:- |:- |:- |:- |
|invoke |Function |否 | |拦截前触发 | |
|success |Function |否 | |成功回调拦截 | |
|fail |Function |否 | |失败回调拦截 | |
|complete |Function |否 | |完成回调拦截 | |
**示例**
```javascript
uni.request({
url: 'request/login', //仅为示例,并非真实接口地址。
success: (res) => {
console.log(res.data);
// 打印: {code:1,...}
}
});
uni.addInterceptor('request', {
invoke(args) {
// request 触发前拼接 url
args.url = 'https://www.example.com/'+args.url
},
success(args) {
// 请求成功后,修改code值为1
args.data.code = 1
},
fail(err) {
console.log('interceptor-fail',err)
},
complete(res) {
console.log('interceptor-complete',res)
}
})
```
### uni.removeInterceptor(STRING)
删除拦截器
**STRING 参数说明**
需要删除拦截器的`api`名称
**示例**
```javascript
uni.removeInterceptor('request')
```
\ No newline at end of file
......@@ -62,7 +62,7 @@ const bgAudioMannager = uni.getBackgroundAudioManager();
bgAudioMannager.title = '致爱丽丝';
bgAudioMannager.singer = '暂无';
bgAudioMannager.coverImgUrl = 'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/7fbf26a0-4f4a-11eb-b680-7980c8a877b8.png';
bgAudioMannager.src = '1. https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3';
bgAudioMannager.src = 'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3';
```
......
......@@ -20,7 +20,7 @@
|参数名|类型|默认值|必填|说明|平台差异说明|
|:-|:-|:-|:-|:-|:-|
|count|Number|100|否|最多可以选择的图片张数|见下方说明|
|count|Number|100|否|最多可以选择的文件数量|见下方说明|
|type|String|'all'|否|所选的文件的类型|见下方说明|
|extension|Array&lt;String&gt;||否|根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。|见下方说明|
|sourceType|Array&lt;String&gt;|['album','camera']|否|(仅在type为`image``video`时可用)`album` 从相册选图,`camera` 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项||
......@@ -54,8 +54,8 @@
|参数|类型|说明|
|:-|:-|:-|
|tempFilePaths|Array&lt;String&gt;|图片的本地文件路径列表|
|tempFiles|Array&lt;Object&gt;、Array&lt;File&gt;|图片的本地文件列表,每一项是一个 File 对象|
|tempFilePaths|Array&lt;String&gt;|文件的本地文件路径列表|
|tempFiles|Array&lt;Object&gt;、Array&lt;File&gt;|文件的本地文件列表,每一项是一个 File 对象|
**File 对象结构如下**
......
......@@ -5,7 +5,8 @@
1. 使用 ``uni.share`` API方式调用社交sdk分享
2. 使用[plus.share.sendWithSystem](http://www.html5plus.org/doc/zh_cn/share.html#plus.share.sendWithSystem)呼起手机os的系统分享菜单
- 小程序:不支持API调用,只能用户主动点击触发分享。可使用自定义按钮方式 &lt;button open-type="share"&gt; 或监听系统右上角的分享按钮 onShareAppMessage 进行自定义分享内容
- H5:如果是普通浏览器,浏览器自带分享按钮;如果是在微信内嵌浏览器中,可调用js-sdk进行分享,[参考](https://ask.dcloud.net.cn/article/35380)|
- H5:如果是普通浏览器,浏览器自带分享按钮;如果是在微信内嵌浏览器中,可调用js-sdk进行分享,[参考](https://ask.dcloud.net.cn/article/35380)
- APP:可以直接使用已经封装好的uni-share插件[详情](https://ext.dcloud.net.cn/plugin?id=4860)
### uni.share(OBJECT)
uni-app的App引擎已经封装了微信、QQ、微博的分享SDK,开发者可以直接调用相关功能。
......@@ -350,7 +351,7 @@ App端可调用手机的系统分享,实现所有注册分享的应用的呼
小程序中用户点击分享后,在 js 中定义 onShareAppMessage 处理函数(和 onLoad 等生命周期函数同级),设置该页面的分享信息。
* 用户点击分享按钮的时候会调用。这个分享按钮可能是小程序右上角原生菜单自带的分享按钮,也可能是开发者在页面中放置的分享按钮(\<button open-type="share">);
* 用户点击分享按钮的时候会调用。这个分享按钮可能是小程序右上角原生菜单自带的分享按钮,也可能是开发者在页面中放置的分享按钮(`<button open-type="share">`);
* 此事件需要 return 一个Object,用于自定义分享内容。
微信小程序平台的分享管理比较严格,请参考 [小程序分享指引](https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share.html)
......
**一键生成iOS通用链接**
#### 背景介绍:
> Universal Link是苹果在WWDC 2015上提出的iOS 9的新特性之一。此特性类似于深层链接,并能够方便地通过打开一个Https链接来直接启动您的客户端应用(手机有安装App)。对比以往所使用的URLSheme, 这种新特性在实现web-app的无缝链接时,能够提供极佳的用户体验。
使用前请阅读[苹果官方文档](https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html#//apple_ref/doc/uid/TP40016308-CH12-SW1)
> 由于苹果iOS 13系统版本安全升级,微信SDK1.8.6版本要求支持Universal Links方式跳转,以便进行合法性校验,提升安全性。更多详情请参考[微信官方说明](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html)
大白话:以前你的APP要打开其他APP是[通过URLScheme](http://www.html5plus.org/doc/zh_cn/runtime.html#plus.runtime.launchApplication)实现,后来苹果提出用Https链接来启动,手机上对应的app(已安装),更方便与web-app的无缝对接。微信响应了这个方案。所以大家开发的APP无论是微信登陆、微信支付,还是微信分享等一切会跳转到微信,再跳回来的场景,需要提供这个链接。要不然你的应用打开了微信,微信就打不开你的应用。
如果不配置通用链接,使用新版本HX提交云端打包会失败,提示以下错误信息:
```javascript
Error code = -5000
Error message:
Error: not set parameter 'UniversalLinks' @'oauth-weixin'
```
传统方式配置通用链接需要:
1. 在苹果开发者中心:开启Associated Domains服务
2. 获取相关参数,手动创建apple-app-site-association文件
3. 部署apple-app-site-association文件到自己的云服务器,配置SSL证书解析域名
4. 然后手动在manifest.json中配置Associated Domains(域名)
5. 粘贴通用链接到对应权限模块
6. 在微信开放平台配置通用链接
其中需要注意的细节较多,且调试起来困难繁琐,困扰了大量开发者。
现在通过HbuilderX(3.1.9版起)云打包,支持自动生成apple-app-site-association文件,并自动托管到:自带cdn、ssl等服务的“免费”的云服务空间[uniCloud的前端网页托管](https://uniapp.dcloud.io/uniCloud/hosting),自动完成manifest.json中的相关配置。用自动化技术替代了,如上所示传统方式令人苦恼的(2-5)4个步骤;只需如下三步直接搞定通用链接。
#### 第一步:开启Associated Domains服务
登录[苹果开发者网站](https://developer.apple.com/),在“Certificates, Identifiers & Profiles”页面选择“Identifiers”中选择对应的App ID,确保开启Associated Domains服务
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/2eae9f97-2c4a-4dc8-97e8-e665b0c660e1.png)
**开启Associated Domains服务后需要重新生成profile文件,提交云端打包时使用**
#### 第二步骤 自动生成通用连接(Universal Links)
打开项目的manifest.json文件,在“(App) SDK配置”项中的微信登录(微信分享、微信支付)下的“iOS平台通用链接(Universal Links)”中,
点击如图所示【自动生成】
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/ea2b1e04-a858-4626-b3fa-bd4ddddd0c3b.jpg)
* 注意您必须先开通"uniCloud(阿里云版)云服务空间和开通前端网页托管"[点此查看开通教程](https://ask.dcloud.net.cn/article/38951),按提示完成操作即可。
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/53e0141e-d2d4-496a-b0f2-2359005c0c4e.jpg)
* 注意:通用链接默认域名仅供测试使用,访问频次限制60次/分钟,请勿在正式发行的项目中使用。
* 如何绑定自己的域名详情:[https://uniapp.dcloud.io/uniCloud/hosting?id=domain](https://uniapp.dcloud.io/uniCloud/hosting?id=domain)
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/1e081fdd-27b2-4c0b-8985-7d59756ed313.jpg)
#### 第三步:在微信开放平台配置通用链接
打开微信[开发平台](https://open.weixin.qq.com/),在“管理中心”页面的“移动应用”下找到已经申请的应用(没有申请应用请点击“创建移动应用”新建应用),点击“查看”打开应用详情页面。
在“开发信息”栏后点击修改,在“iOS应用”下的“Universal Links”项中配置应用的通用链接,如下图所示:
![](https://img-cdn-tc.dcloud.net.cn/uploads/article/20191008/e933f7ef8ff078bf05e28a24efee74bd.png)
至此,就已经完成了通用链接的配置全过程,云打包后生效。
#### 其他相关
##### 客户端处理通用链接。
可通过5+ API的plus.runtime.launcher判断应用启动来源,如果其值为"uniLink"则表示通过通用链接启动应。这时可通过5+ API的plus.runtime.arguments获取启动参数,通用链接启动的情况将返回完整的通用链接地址。
例:HBuilderX中自带的默认真机运行基座HBuilderX注册的通用链接:[https://demo.dcloud.net.cn/ulink/](https://demo.dcloud.net.cn/ulink/)
##### 通用链接生成原理:
1. 选择云空间获取云空间的默认/自定义域名
2. 按提前制定的规范(uni-universallinks/DCloud appid)拼接URL
3. 根据现有参数自动生成通用链接相关参数到manifest.json
4. 发起云打包时读取证书的profile文件生成apple-app-site-association并部署到前面选定的云空间根目录的.well-known目录下(请勿删除该文件,否则通用链接将失效)
###### 注意事项:
- 通用链接指向的路径可以为空,他只是一种信息传递方式。可以简单地理解为:通过解析URL的“/”后的参数到apple-app-site-association中找到指定的包名并唤醒对应的APP
- 通用链接内容保存在manifest.json中"云打包后生效",被手机读取的时机是应用被安装的时候。如果你的通用链接内容有变化,你需要重新提交云打包,并重新安装一次应用才能生效
- 通用链接最终托管在服务端,如有变动注意缓存的清理,例如尝试重启手机等操作
>如果你是本地离线打包或者由于某种原因你需要用传统的方式:私有化部署服务器来托管apple-app-site-association文件创建通用链接。你仍然可以通过手动配置manifest.json实现。详情:[https://ask.dcloud.net.cn/article/36393#unilink](https://ask.dcloud.net.cn/article/36393#unilink)
##### 常见问题
1. 如何验证通用链接已经生效,有什么表现或者测试方案
你可以将通用链接输入到iphone自带Safari浏览器中,下拉即可看到通用链接对应到应用名称和一个打开按钮,点击按钮即可直接在浏览器打开对应的APP。详情:[点此查看演示视频](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/4e920b86-0f67-45ac-81f6-6b97f87ff0ae.mp4)
\ No newline at end of file
......@@ -13,7 +13,7 @@
|method|String|否|GET|有效值详见下方说明||
|timeout|Number|否|60000|超时时间,单位 ms|H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序|
|dataType|String|否|json |如果设为 json,会尝试对返回的数据做一次 JSON.parse||
|responseType|String|否|text |设置响应的数据类型。合法值:text、arraybuffer|App和支付宝小程序不支持|
|responseType|String|否|text |设置响应的数据类型。合法值:text、arraybuffer|支付宝小程序不支持|
|sslVerify|Boolean|否|true|验证 ssl 证书|仅App安卓端支持(HBuilderX 2.3.3+)|
|withCredentials|Boolean|否|false|跨域请求时是否携带凭证(cookies)|仅H5支持(HBuilderX 2.6.15+)|
|firstIpv4|Boolean|否|false|DNS解析时优先使用ipv4|仅 App-Android 支持 (HBuilderX 2.8.0+)|
......
......@@ -45,7 +45,7 @@ uni.onAccelerometerChange(function (res) {
|参数名|类型|默认|必填|说明|平台差异说明|
|:-|:-|:-|:-|:-|:-|
|interval|String|normal|否|接口调用成功的回调|微信小程序、百度小程序|
|interval|String|normal|否|监听加速度数据回调函数的执行频率|微信小程序、百度小程序|
|success|Function||否|接口调用成功的回调||
|fail|Function||否|接口调用失败的回调函数||
|complete|Function||否|接口调用结束的回调函数(调用成功、失败都会执行)|&nbsp;|
......
......@@ -12,7 +12,7 @@
|参数名|类型|必填|说明|平台差异说明|
|:-|:-|:-|:-|:-:|
|onlyFromCamera|Boolean|否|是否只能从相机扫码,不允许从相册选择图片|字节跳动小程序不支持此参数|
|scanType|Array|否|扫码类型,参数类型是数组,二维码是'qrCode',一维码是'barCode',DataMatrix是‘datamatrix’,pdf417是‘pdf417’。|字节跳动小程序不支持此参数,支付宝只支持条码和二维码|
|scanType|Array|否|扫码类型,参数类型是数组,二维码是'qrCode',一维码是'barCode',DataMatrix是‘datamatrix’,pdf417是‘pdf417’。|字节跳动小程序不支持此参数|
|success|Function|否|接口调用成功的回调,返回内容详见返回参数说明。||
|fail|Function|否|接口调用失败的回调函数(识别失败、用户取消等情况下触发)||
|complete|Function|否|接口调用结束的回调函数(调用成功、失败都会执行)|&nbsp;|
......
......@@ -13,8 +13,8 @@
|参数|说明|平台差异说明|
|:-|:-|:-|
|brand|手机品牌|App、微信小程序、百度小程序、字节跳动小程序、QQ小程序|
|model|手机型号||
|brand|设备品牌|App、微信小程序、百度小程序、字节跳动小程序、QQ小程序|
|model|设备型号|全平台支持。H5(3.1.10+)新增`PC`|
|pixelRatio|设备像素比||
|screenWidth|屏幕宽度||
|screenHeight|屏幕高度||
......@@ -34,11 +34,12 @@
|host|宿主平台|百度小程序|
|app|当前运行的客户端|支付宝小程序|
|cacheLocation|上一次缓存的位置信息|百度小程序|
|system|操作系统版本||
|platform|客户端平台,值域为:`ios``android`||
|system|操作系统名称及版本,如Android 10||
|platform|客户端平台,值域为:`ios``android``mac(3.1.10+)``windows(3.1.10+)``linux(3.1.10+)`||
|fontSizeSetting|用户字体大小设置。以“我-设置-通用-字体大小”中的设置为准,单位:px|微信小程序、支付宝小程序、百度小程序、QQ小程序|
|SDKVersion|客户端基础库版本|支付宝小程序和H5不支持|
|swanNativeVersion|宿主平台版本号|百度小程序|
|benchmarkLevel|设备性能等级。取值为:-2 或 0(该设备无法运行小游戏),-1(性能未知),>=1(设备性能值,该值越高,设备性能越好,目前最高不到50)|微信小程序Android版|
|albumAuthorized | 允许微信使用相册的开关(仅 iOS 有效) |微信小程序|
|cameraAuthorized | 允许微信使用摄像头的开关 |微信小程序|
|locationAuthorized | 允许微信使用定位的开关 |微信小程序|
......@@ -105,8 +106,8 @@ uni.getSystemInfo({
|参数|说明|平台差异说明|
|:-|:-|:-|
|brand|手机品牌|App、微信小程序、百度小程序、字节跳动小程序、QQ小程序|
|model|手机型号||
|brand|设备品牌|App、微信小程序、百度小程序、字节跳动小程序、QQ小程序|
|model|设备型号|全平台支持。H5(3.1.10+)新增`PC`|
|pixelRatio|设备像素比||
|screenWidth|屏幕宽度||
|screenHeight|屏幕高度||
......@@ -127,7 +128,7 @@ uni.getSystemInfo({
|app|当前运行的客户端|支付宝小程序|
|cacheLocation|上一次缓存的位置信息|百度小程序|
|system|操作系统版本||
|platform|客户端平台,值域为:`ios``android`||
|platform|客户端平台,值域为:`ios``android``mac(3.1.10+)``windows(3.1.10+)``linux(3.1.10+)`||
|fontSizeSetting|用户字体大小设置。以“我-设置-通用-字体大小”中的设置为准,单位:px|微信小程序、支付宝小程序、百度小程序、QQ小程序|
|SDKVersion|客户端基础库版本|支付宝小程序和H5不支持|
|swanNativeVersion|宿主平台版本号|百度小程序|
......
......@@ -167,7 +167,7 @@ view.boundingClientRect(data => {
```
**注意**
- nvue 暂不支持 uni.createSelectorQuery,暂时使用下面的方案
- nvue 已经支持 uni.createSelectorQuery,无需再使用下面的方案
```
<template>
......
......@@ -8,5 +8,7 @@
|uniCloud.database() |客户端访问云数据库,获取云数据库对象引用 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb) |
|uniCloud.uploadFile() |客户端直接上传文件到云存储 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=uploadfile) |
|uniCloud.getTempFileURL() |客户端获取云存储文件的临时路径 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=gettempfileurl) |
|uniCloud.getCurrentUserInfo() |客户端获取当前用户信息 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=client-getcurrentuserinfo) |
DCloud有**800万**开发者,[uni统计](https://tongji.dcloud.net.cn/)手机端月活**12亿**。是开发者数量和案例最丰富的多端开发框架。
DCloud有**800万**开发者,[uni统计](https://tongji.dcloud.net.cn/)手机端月活**12亿+**。是开发者数量和案例最丰富的多端开发框架。
欢迎知名开发商[提交案例](https://github.com/dcloudio/uni-app/issues/6)或接入[uni统计](https://tongji.dcloud.net.cn/)
......@@ -222,7 +222,7 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
#### 互联网公司
**华为:** 微信小程序搜索“荣耀亲选商城”、[H5](https://m.qinxuan.honor.cn/)[App部分栏目使用DCloud SDK](https://appgallery1.huawei.com/#/app/C100382765)
**华为:** 荣耀商城。微信小程序搜索“荣耀亲选商城”、[H5](https://m.qinxuan.honor.cn/)[App部分栏目使用DCloud SDK](https://appgallery1.huawei.com/#/app/C100382765)
**华为:** [华为大学H5版](https://developer.huaweiuniversity.com/m/)
......@@ -230,12 +230,22 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**美团:** 微信小程序搜索“美团充电宝”、App内充电宝栏目
**快手:** App中搜索“快手每日一答”
**快手:** 微信小程序搜索“快手短视频”、App中搜索“快手每日一答”
**腾讯:** 微信小程序搜索“腾讯全民模拟炒股大赛”、[H5(需使用微信浏览器打开)](https://zqact.tenpay.com/chaogu/)
**腾讯医生:** 微信小程序搜索“腾讯医生”、[H5](https://doctor.baike.qq.com/)
**腾讯企业邮箱:** [H5](https://exmail.qq.com/qy_mina_logic/uniapp/h5)
**腾讯手游助手:** [H5](https://bbs.syzs.qq.com/)
**腾讯地图:** App内穿梭线路栏目
**腾讯财付通:** 微信小程序搜索“腾讯全民模拟炒股大赛”、[H5(需使用微信浏览器打开)](https://zqact.tenpay.com/chaogu/)
**京东:** 京东开发的新冠抗疫服务平台:[H5](http://yingji-h5.chanye.jdcloud.com/)、京东金融羊羊大作战:[H5](https://u.jr.jd.com/uc-fe-wxgrowing/sheep-fight/)
**vivo技术中台:** vivo利用uni-app打造悟空中台,悟空中台介绍[详见](https://mp.weixin.qq.com/s/oGX4XSm8F4fa1ocLdpyqlA)
**vivo官方商城:**微信小程序搜索"vivo",支付宝搜索 "vivo"
<div class="scan-code">
......@@ -247,6 +257,10 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
</div>
</div>
**小米:** 米家App内米家智能厨房页面,[App内H5](https://g.home.mi.com/partner/nfc/prod/index.html?m=chunmi.ihcooker.slim#/);lbs门店微信群:[微信H5](http://s1.mi.com/m/wx/lbs/#/)
**携程微商城:** [微信H5](https://m.ctrip.com/webapp/hotelofficial/?#/)
**搜狐狐友圈:**微信、支付宝、百度、头条小程序均支持。
**中华英才网:** 百度小程序搜索“中华英才网”
......@@ -255,7 +269,7 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**开源中国:** 微信小程序搜索“osc+”、百度小程序搜索“开源中国社区”
**网易藏宝阁:** 部分栏目使用uni小程序sdk实现[App下载](https://cbg.163.com/app/)
**网易藏宝阁:** [uni小程序SDK](https://nativesupport.dcloud.net.cn)案例,部分栏目做成小程序形态[App下载](https://cbg.163.com/app/)
**联想集团官方小程序:** 微信小程序搜索 “联想集团”
......@@ -265,6 +279,23 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**西祠胡同:** [App官网扫码下载](https://www.xici.net/)[H5](https://3g.xici.net/)
**极米:** [极米官方app](https://sj.qq.com/myapp/detail.htm?apkName=com.xgimi.zhushou&info=FB45015C23ACF368D22855D6C4964312)[官网H5版](https://m.xgimi.com/)、微信小程序搜索“极米官方商城”、微信小程序搜索“极米care+”售后服务宣传
**货拉拉:** App部分栏目使用uni小程序sdk。
**叮咚买菜:** 微信小程序搜索 “叮咚买菜”、[公众号H5](http://wx.m.ddxq.mobi/#/)
**百度:** 众测平台用户反馈系统,[H5](http://fans.baidu.com/fanstest/wapindex?product_id=1009&version=3.2.9&client_type=iOS&contact_way=qq)
**新浪健康:** 病情咨询,[H5](https://health.sina.cn/patient_consult_h5/)
**爱奇艺:** i联盟,[H5](https://vip.iqiyi.com/html5VIP/activity/person-union/#/)
**智联招聘:** WeTalk智能问答系统,[H5](https://special.zhaopin.com/h5/2020/sh/dhzc061717/)
**金山:** WPS智能PPT,[H5](https://aippt.wps.cn/m/)
<!-- **达内在线:** 达内教育的在线培训App。[App官网下载](http://www.tmooc.cn/app/index.shtml) -->
#### SaaS服务商
......@@ -295,6 +326,8 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**广东汕头公交:** 广东移动出品。[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.gmcc.stgj)[iOS](https://apps.apple.com/cn/app/%E6%B1%95%E5%A4%B4%E5%85%AC%E4%BA%A4/id1091442840)、微信小程序搜索“汕头智慧公交”
**中国电信189福利站:** [App内福利站页面](https://www.189.cn/client/actcenter/signActivityH5/welfare2/index1.html#/)
**广东联通粉丝卡:**[H5(特定UA)](https://wxv.gd10010.cn/)
**云南移动微店系统:**[H5](http://wx.10086.cn/yunnan/qrcodeyn/uniapph5/h5/index.html)
......@@ -334,7 +367,7 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**苍南农商银行** 丰收联盟。[H5](https://wxmapp.zjcnbank.com/)
**平安集团:**金管家多个页面,[H5](https://laip-gbr-pai.pingan.com/static/goodStart/#/)
**平安集团:** 智慧医疗慢病管理,[H5](https://hm.city.pingan.com/h5/);金管家多个页面,[H5](https://laip-gbr-pai.pingan.com/static/goodStart/#/);口袋合伙人,[H5](https://b.pingan.com.cn/mkt/youhui/2012/kdhhrzhjh/#/package-act21/pages/act-zhlx/index);易骑行,[H5](https://ebs.yun.city.pingan.com/pc/mini/#/)
**拉卡拉收款宝:** App部分页面使用uni-app制作
......@@ -370,10 +403,14 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
<!-- **上海闵行区委党务公开网:**[H5(有UA限制)](http://dj.mhdw.gov.cn/djwx/) -->
**粤苗:** 广东省疾病预防控制中心疫苗预约管理 [官网app下载](http://cdcp.gd.gov.cn/ggwsfwxx/content/post_3146600.html)
**广东省工会:**粤工惠,广东工友服务App,[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.gdftu.ygh)[iOS](https://apps.apple.com/cn/app/id1464193434) 、微信小程序搜索“粤工惠”
**广东省广州民政局:**[微信H5](https://wxpt.gzmz.gov.cn/ydzw-wx/#/pagesA/login/index)
**广东省共青团:** [12355.net](https://12355.net)
**广州市公安局南沙区分局:** 微警[微信H5](https://ns.weijing.gov.cn/wechat-app/)
**广州市南沙区企业综合服务平台:**[H5](https://qiye.gzns.gov.cn/m/#/)
......@@ -500,27 +537,36 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**五粮液:** 内部管理系统
#### html5游戏
**全家超市** App部分页面使用uni-app制作
#### 游戏
**信任的进化:** 曾Taptap首页推荐的益智小游戏。[Android](http://sj.qq.com/myapp/detail.htm?apkName=com.xuangames.xrdjh)[iOS](https://itunes.apple.com/cn/app/%E4%BF%A1%E4%BB%BB%E7%9A%84%E8%BF%9B%E5%8C%96-%E5%90%88%E4%BD%9C%E8%87%AA%E7%A7%81%E7%9A%84%E5%9F%BA%E5%9B%A0/id1290206167?mt=8)
**出发吧!冒险家:** 曾Taptap首页推荐的冒险游戏。[Android](https://www.seagame.com/mxj/android1.apk)[iOS](https://apps.apple.com/cn/app/id1367825240)
**萌猫合成:** 网赚类合成游戏 [App](https://ext.dcloud.net.cn/plugin?id=4095)
**有奖猜歌:** 猜歌有奖,激励视频变现 [App](https://ext.dcloud.net.cn/plugin?id=4826)
#### 创业公司
**Crimaster犯罪大师:**火爆的全球推理侦探专属社区。[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.ultron.crimaster)[iOS](https://apps.apple.com/cn/app/crimaster%E7%8A%AF%E7%BD%AA%E5%A4%A7%E5%B8%88/id1501701702)
**宝贝听听:** 腾讯投资的创业公司,中国最大的儿童有声早教平台。[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.kunpeng.babyting&info=A20D77EAD610031E8F8C6D1A16135ADD)[iOS](https://apps.apple.com/cn/app/%E5%AE%9D%E8%B4%9D%E5%90%AC%E5%90%AC%E6%95%85%E4%BA%8B%E4%B9%A6-%E5%84%BF%E7%AB%A5%E7%9D%A1%E5%89%8D%E6%95%85%E4%BA%8B%E5%84%BF%E6%AD%8C%E5%A4%A7%E5%85%A8/id480111612)、微信小程序搜索“宝贝听听”
**本地宝:** 本地宝(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通用链接](http://m3w.cn/cst)
**安咕在家早教:**0-6岁宝宝能力跟踪发展工具,[iOS](https://itunes.apple.com/cn/app/%E5%AE%89%E5%92%95%E5%9C%A8%E5%AE%B6%E6%97%A9%E6%95%99/id1455168710?mt=8)[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.angubaby.earlyeduhome)、微信小程序搜索“安咕在家早教”。
**批改网(5+App):**智能批改,辅助英文教与学,[Android](http://sj.qq.com/myapp/detail.htm?apkName=org.pigai.allround)[iOS](https://itunes.apple.com/cn/app/id1158628103)
<!--
**加减号:**专业健身健身App,[Android和iOS](https://www.jvhv.com/wap/pages/index/download/download)[H5](https://www.jvhv.com)
**弈客围棋(5+App):**Appstore体育分类排名前100的棋友App。[iOS](https://apps.apple.com/cn/app/yi-ke-wei-qi-quan-qiu-yi-wan/id988682022)
-->
**新疆包邮:**新疆网民的专属导购APP。[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.h5415379.wux)[iOS](https://apps.apple.com/cn/app/%E6%96%B0%E7%96%86%E5%8C%85%E9%82%AE/id1433935701)
**蓝鲸鱼旧物回收:** 微信、支付宝搜索“蓝鲸鱼旧物回收”
......@@ -532,8 +578,6 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**易学啦:**易学啦致力于为中学生提供免费的学习资料和更科学的学习方法和技巧。[App码](//m3w.cn/__uni__4af5e77)
**小情绪:**一款随时随地分享您的心情及图片的应用。[App和小程序通用码](//m3w.cn/__uni__2d73605)
**纸塘日记:**一款简约的记录生活的应用。[App码和小程序通用码](//m3w.cn/__uni__55a7b4e)
**指掌短信:**App、小程序、电脑版,全平台发送短信(小程序搜“指掌短信”),**<span id="zhizhang" style="color:#42b983;cursor: pointer;">开发者致DCloud的感谢信</span>**[App及H5的通用链接](//m3w.cn/__uni__7ffa4e9)
......@@ -546,9 +590,15 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**壹恒出行:**共享汽车,APP内线上找到距离你最近的网点或汽车,[iOS](https://itunes.apple.com/cn/app/%E5%A3%B9%E6%81%92%E5%87%BA%E8%A1%8C/id1455172086?mt=8)[Android](http://appstore.huawei.com/app/C100659807)
**肆台:**看见世界,让世界看见(使用 nvue 实现的新闻 App)。[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.sitai.zlstyle)
**律师来电:** 专业法律咨询,[H5](https://www.lvshilaidian.com)
**魔叮:** 建筑制图众包平台,[H5](https://www.emoding.com)
**就爱肚皮舞** 肚皮舞专业社区,[Android及iOS](http://www.92dpw.com/m.php?module=down)
**新疆包邮:**新疆网民的专属导购APP。[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.h5415379.wux)[iOS](https://apps.apple.com/cn/app/%E6%96%B0%E7%96%86%E5%8C%85%E9%82%AE/id1433935701)
**萤火e券:**一个会省钱的购物app。[Android](http://m3w.cn/yheq)
**萤火e券:**一个会省钱的购物app。[App、H5、小程序通用链接](http://m3w.cn/yheq)
**卷优网:**淘宝天猫优惠券,千万别错过。[Android](http://m3w.cn/jyw)
......@@ -558,10 +608,6 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**蚂蚁宝充电:**海德龙新能源充电桩服务。使用微信或App扫码,均能快速充电。微信小程序搜索“蚂蚁宝充电”。
**云省购:**导购App,集淘宝、天猫、京东等电商购物平台的优惠信息,让用户花更少的钱买同样的商品。[Android及H5](http://m3w.cn/yunshenggou)
**品聚:**以艺术品为主体的高品质综合性交易平台,[Android和iOS](http://ibuying.com/download)
**寻寓租房:**一个便捷省事的租房APP,[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.xunyu.io)
**优十美:**会员尊享vip一卡通,[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.youmeimall.youmeimall)、微信小程序搜索“优十美”。
......@@ -584,8 +630,6 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**转门面网:**出租转让招商、开店选址、经营策略首选转门面网。[iOS、Android统一发布页](http://m3w.cn/zmmw)
**品沉浮 • 醉一生:**评鉴好茶,[H5](https://tea.skycto.com)
**闪招:**主推校园应届毕业生就业和为用人单位提供就业人才,[Android](http://appstore.huawei.com/app/C100671609)
**晴空万里:**天气实时预报,精简小巧。[Android](https://m3w.cn/qkwl)
......@@ -594,12 +638,6 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**大象优车:**为车商创造价值。[iOS](https://apps.apple.com/cn/app/%E5%A4%A7%E8%B1%A1%E4%BC%98%E8%BD%A6-%E4%B8%BA%E8%BD%A6%E5%95%86%E5%88%9B%E9%80%A0%E4%BB%B7%E5%80%BC/id1461035002)[Android](http://a.app.qq.com/o/simple.jsp?pkgname=com.daxiangauto.apps)
**律师来电:** 专业法律咨询,[H5](https://www.lvshilaidian.com)
**魔叮:** 建筑制图众包平台,[H5](https://www.emoding.com)
**就爱肚皮舞** 肚皮舞专业社区,[Android及iOS](http://www.92dpw.com/m.php?module=down)
**优加:** 微商分销,[Android](http://a.app.qq.com/o/simple.jsp?pkgname=com.king.youplus)
**看书阅读神器:**[H5](https://book.yw98.com/h5/#/)
......@@ -642,8 +680,6 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**拾阅草堂:**网络小说。[微信小程序码](https://user-images.githubusercontent.com/12842804/61346867-371ccc00-a88d-11e9-8386-18e27677869c.png)
**千家找房:**二手房、新房买卖租赁平台。各大应用商城搜索“千家找房”下载APP、[H5](https://m.allqj.com)[微信小程序二维码](https://user-images.githubusercontent.com/31872878/62843602-a3081e00-bced-11e9-8a2d-3f997be6cacf.png)
**坤典智慧农场:**体验农村种植、养殖的生活,足不出户就可以租地种植自己的蔬菜了,养殖鸡鸭牛羊,通过视频远程查看。[iOS码](https://user-images.githubusercontent.com/29654065/63156422-3cfdfc80-c047-11e9-8c41-23d298279466.jpg)[Android码](https://user-images.githubusercontent.com/29654065/63156422-3cfdfc80-c047-11e9-8c41-23d298279466.jpg)[微信小程序码](https://user-images.githubusercontent.com/29654065/63156422-3cfdfc80-c047-11e9-8c41-23d298279466.jpg)[H5码](https://user-images.githubusercontent.com/29654065/63156422-3cfdfc80-c047-11e9-8c41-23d298279466.jpg)
**指动全城:**一个为宝宝选择好产品的线上渠道。[App和小程序通用链接](https://m3w.cn/__uni__6020544)
......@@ -654,8 +690,6 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**斗豆侠:**购物App。[iOS](https://apps.apple.com/cn/app/id1395120441)[Android](https://obs.myhwclouds.com/vipbean/xgyx_guns/APK/yq.apk)
**RUCY:**衣着搭配。[Android](https://appstore.huawei.com/app/C101136185)[iOS](https://apps.apple.com/cn/app/rucy/id1479275199)
**BookChat:**通用电子书应用。[iOS](https://apps.apple.com/cn/app/id1481932361)[Android](https://www.pgyer.com/bookchat-app)
**稀饭旅行小程序:**微信、百度搜索 稀饭旅行
......
......@@ -54,7 +54,7 @@
<img src="https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/759713d0-4f2d-11eb-a16f-5b3e54966275.png" width="20" height="20"/>
<div class="contact-smg">
<div>官方QQ交流群</div>
<div>群24:672494800 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=7ntnubNkRwi2DlXS02C4OEFfm2KbvnBu&jump_from=webapi">点此加入</a></div>
<div>群27:811363410 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=noDvG6kfZgzXh-Wbp5MRhNutYCojx08G&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -63,10 +63,10 @@
<div>群30:371046920(2000人已满)</div>
<div>群29:202965481(2000人已满)</div>
<div>群28:166188776(2000人已满)</div>
<div>群27:811363410(2000人已满)</div>
<!-- <div>群27:811363410(2000人已满)</div> -->
<div>群26:147867597(2000人已满)</div>
<div>群25:165297000(2000人已满)</div>
<!-- <div>群24:672494800(2000人已满)</div> -->
<div>群24:672494800(2000人已满)</div>
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<div>群21:717019120(2000人已满)</div>
......
......@@ -416,7 +416,7 @@ uni-app 2.9+ 新增 leftWindow, topWindow, rightWindow 配置。用于解决宽
|homeButton|Boolean|false|标题栏控件是否显示Home按钮||
|autoBackButton|Boolean|true|标题栏控件是否显示左侧返回按钮|2.6.3|
|backButton|Object||返回按钮的样式,详见:[backButton](/collocation/pages?id=app-titleNView-backButtonStyles)|2.6.3|
|backgroundImage|String||支持以下类型: 背景图片路径 - 如"./img/t.png",仅支持本地文件路径, 相对路径,相对于当前页面的host位置,根据实际标题栏宽高拉伸绘制; 渐变色 - 仅支持线性渐变,两种颜色的渐变,如“linear-gradient(to top, #a80077, #66ff00)”, 其中第一个参数为渐变方向,可取值: "to right"表示从左向右渐变, “to left"表示从右向左渐变, “to bottom"表示从上到下渐变, “to top"表示从下到上渐变, “to bottom right"表示从左上角到右下角, “to top left"表示从右下角到左上角|2.6.3|
|backgroundImage|String||支持以下类型: 背景图片路径 - 如"/static/img.png",仅支持本地文件绝对路径,根据实际标题栏宽高拉伸绘制; 渐变色 - 仅支持线性渐变,两种颜色的渐变,如“linear-gradient(to top, #a80077, #66ff00)”, 其中第一个参数为渐变方向,可取值: "to right"表示从左向右渐变, “to left"表示从右向左渐变, “to bottom"表示从上到下渐变, “to top"表示从下到上渐变, “to bottom right"表示从左上角到右下角, “to top left"表示从右下角到左上角|2.6.3|
|backgroundRepeat|String||仅在backgroundImage设置为图片路径时有效。 可取值: "repeat" - 背景图片在垂直方向和水平方向平铺; "repeat-x" - 背景图片在水平方向平铺,垂直方向拉伸; “repeat-y” - 背景图片在垂直方向平铺,水平方向拉伸; “no-repeat” - 背景图片在垂直方向和水平方向都拉伸。 默认使用 “no-repeat"|2.6.3|
|titleAlign|String|"auto"|可取值: "center"-居中对齐; "left"-居左对齐; "auto"-根据平台自动选择(Android平台居左对齐,iOS平台居中对齐)|2.6.3|
|blurEffect|String|"none"|此效果将会高斯模糊显示标题栏后的内容,仅在type为"transparent"或"float"时有效。 可取值: "dark" - 暗风格模糊,对应iOS原生UIBlurEffectStyleDark效果; "extralight" - 高亮风格模糊,对应iOS原生UIBlurEffectStyleExtraLight效果; "light" - 亮风格模糊,对应iOS原生UIBlurEffectStyleLight效果; "none" - 无模糊效果。 注意:使用模糊效果时应避免设置背景颜色,设置背景颜色可能覆盖模糊效果。|2.4.3|
......
* [组件概述](component/)
* [vue组件](component/vue-component.md)
* 视图容器
* [view](component/view.md)
* [scroll-view](component/scroll-view.md)
......@@ -44,6 +45,7 @@
* 广告
* [ad](component/ad.md)
* [ad-draw](component/ad-draw.md)
* [Grid 广告](component/ad-grid.md)
* 页面属性配置节点
* [page-meta](component/page-meta.md)
* [navigation-bar](component/navigation-bar.md)
......@@ -144,7 +146,7 @@
<img src="https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/759713d0-4f2d-11eb-a16f-5b3e54966275.png" width="20" height="20"/>
<div class="contact-smg">
<div>官方QQ交流群</div>
<div>群24:672494800 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=7ntnubNkRwi2DlXS02C4OEFfm2KbvnBu&jump_from=webapi">点此加入</a></div>
<div>群27:811363410 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=noDvG6kfZgzXh-Wbp5MRhNutYCojx08G&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -153,10 +155,10 @@
<div>群30:371046920(2000人已满)</div>
<div>群29:202965481(2000人已满)</div>
<div>群28:166188776(2000人已满)</div>
<div>群27:811363410(2000人已满)</div>
<!-- <div>群27:811363410(2000人已满)</div> -->
<div>群26:147867597(2000人已满)</div>
<div>群25:165297000(2000人已满)</div>
<!-- <div>群24:672494800(2000人已满)</div> -->
<div>群24:672494800(2000人已满)</div>
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<div>群21:717019120(2000人已满)</div>
......
## Grid 广告
### 简介
开发者可以使用 ad 组件创建 Grid 广告组件,Grid 广告组件在创建后会自动拉取广告数据并显示。
**平台差异说明**
|App|H5|微信小程序|支付宝小程序|百度小程序|字节跳动小程序|QQ小程序|快应用|360小程序|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|x|x|√|x|x|x|x|x|x|
**开通配置广告**
开通广告步骤:
1. 开通广告
需在广告平台后台操作:
* App平台:[https://uniad.dcloud.net.cn/](https://uniad.dcloud.net.cn/)
* 小程序平台:在各自的小程序管理后台操作。
2. 申请广告位id
在各位后台申请广告位id
3. 在页面合适位置编写代码,放置ad组件,配上广告位id(app是adpid,微信、头条、qq小程序是unit-id,百度小程序是apid)
4. App端打包后生效,打包时必须选择要集成的广告SDK(穿山甲、广点通、360联盟、快手)。
**属性说明**
|属性名|类型|默认值|说明|平台差异|
|:-|:-|:-|:-|:-|
|unit-id|String||广告单元id,可在小程序管理后台的流量主模块新建|微信小程序|
|ad-type|String|grid||微信小程序|
|@load|EventHandle||广告加载成功的回调||
|@error|EventHandle||广告加载失败的回调||
|@close|EventHandle||广告关闭的回调||
### 广告尺寸设置
Grid 广告不允许直接设置样式属性,默认宽度为100%(width: 100%),高度会自动等比例计算,因此开发者可以设置广告外层组件的宽度调整广告的尺寸。格子广告有最小尺寸限制,5个的形态为331px,8个的形态为294px。
```html
<view class="adContainer">
<ad unit-id="xxxx" ad-type="grid" ad-theme="white" grid-count="5"></ad>
</view>
```
```css
<style>
/* 外层组件的宽度可设置成100%或具体数值 */
.adContainer {
width: 100%;
}
<style>
```
### 广告事件监听
Grid 广告在创建后会自动拉取广告。开发者可以通过 ad 组件的 load 和 error 事件监听广告拉取成功或失败,可以通过 close 事件监听广告被关闭。
```html
<view class="adContainer">
<ad unit-id="xxxx" ad-type="grid" ad-theme="white" grid-count="5" @load="adLoad" @error="adError" @close="adClose"></ad>
</view>
```
```js
<script>
export default {
data() {
return {
}
},
methods: {
adLoad() {
},
adError(e) {
},
adClose(e) {
}
}
}
</script>
```
### 广告主题样式设置
广告组件提供黑、白两种主题样式,开发者可以在创建广告时传入ad-theme参数实现主题样式选择,ad-theme参数为字符串类型,参数值可选white, black
```
<view class="adContainer">
<ad unit-id="xxxx" ad-type="grid" ad-theme="white"></ad>
</view>
```
```
<view class="adContainer">
<ad unit-id="xxxx" ad-type="grid" ad-theme="black"></ad>
</view>
```
### 广告格子个数设置
广告组件提供黑、白两种主题样式,开发者可以在创建广告时传入grid-count参数实现主题样式选择,grid-count参数为数字类型,参数值可选5, 8
```
<view class="adContainer">
<ad unit-id="xxxx" ad-type="grid" grid-count="5"></ad>
</view>
```
```
<view class="adContainer">
<ad unit-id="xxxx" ad-type="grid" grid-count="8"></ad>
</view>
```
......@@ -62,7 +62,7 @@ export default {
poster: 'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/7fbf26a0-4f4a-11eb-b680-7980c8a877b8.png',
name: '致爱丽丝',
author: '暂无',
src: '1. https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3',
src: 'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3',
},
audioAction: {
method: 'pause'
......
......@@ -63,7 +63,7 @@
|share|触发用户转发|微信小程序、百度小程序、支付宝小程序、字节跳动小程序、QQ小程序|
|getUserInfo|获取用户信息,可以从@getuserinfo回调中获取到用户信息,包括头像、昵称等信息|微信小程序、百度小程序、QQ小程序|
|contact | 打开客服会话,如果用户在会话中点击消息卡片后返回应用,可以从 @contact 回调中获得具体信息 |微信小程序、百度小程序|
|getPhoneNumber | 获取用户手机号,可以从@getphonenumber回调中获取到用户信息|微信小程序、百度小程序、字节跳动小程序、支付宝小程序 |
|getPhoneNumber | 获取用户手机号,可以从@getphonenumber回调中获取到用户信息|微信小程序、百度小程序、字节跳动小程序、支付宝小程序。App平台另见[一键登陆](https://uniapp.dcloud.net.cn/univerify) |
|launchApp | 小程序中打开APP,可以通过app-parameter属性设定向APP传的参数|[微信小程序](https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/launchApp.html)[QQ小程序](https://q.qq.com/wiki/develop/miniprogram/frame/open_ability/open_app.html)|
|openSetting | 打开授权设置页 |微信小程序、百度小程序|
|getAuthorize | 支持小程序授权 | 支付宝小程序 |
......
......@@ -387,6 +387,7 @@ mixin是vue的技术,不熟悉的可以点此了解[vue官网的mixin文档](h
|gettree |Boolean | false |是否查询树状数据,默认 `false`|
|startwith |String | '' |`gettree`的第一层级条件,此初始条件可以省略,不传startWith时默认从最顶级开始查询|
|limitlevel |Number | 10 |`gettree`查询返回的树的最大层级。超过设定层级的节点不会返回。默认10级,最大15,最小1|
|foreign-key |String | '' |手动指定使用的关联关系,HBuilderX 3.1.10+ [详情](/uniCloud/clientdb?id=lookup-foreign-key)|
`uniCloud.mixinDatacom` 的data
......
......@@ -50,11 +50,12 @@ app端nvue专用组件。在app-nvue下,如果是长列表,使用list组件
|属性名|说明|类型|默认值|
|:-|:-|:-|:-|
|show-scrollbar|控制是否出现滚动条|boolean|true|
|bounce|控制是否回弹效果|boolean|true|
|bounce|控制是否回弹效果, iOS 不支持动态修改|boolean|true|
|loadmoreoffset|触发 loadmore 事件所需要的垂直偏移距离(设备屏幕底部与 list 底部之间的距离),建议手动设置此值,设置大于0的值即可|number|0|
|offset-accuracy|控制 onscroll 事件触发的频率:表示两次onscroll事件之间列表至少滚动了10px。注意,将该值设置为较小的数值会提高滚动事件采样的精度,但同时也会降低页面的性能|number|10|
|pagingEnabled|是否按分页模式显示List,默认值false|boolean|true/false|
|scrollable|是否允许List滚动|boolean|true/false|
|enable-back-to-top|iOS点击顶部状态栏滚动条返回顶部,只支持竖向|boolean|false|
`loadmoreoffset` 示意图:
......
......@@ -9,8 +9,8 @@ app端nvue专用组件。
#### 子组件
`<recycle-list>` 只能使用 `<cell-slot>` 作为其直接子节点,使用其他节点无效。
#### <cell-slot>
<cell-slot> 代表的是列表每一项的模板,它只用来描述模板的结构,并不对应实际的节点。`<cell-slot>` 的个数只表示模板的种类数,真实列表项的个数是由数据决定的。
#### cell-slot
`<cell-slot>` 代表的是列表每一项的模板,它只用来描述模板的结构,并不对应实际的节点。`<cell-slot>` 的个数只表示模板的种类数,真实列表项的个数是由数据决定的。
**注意**
- `<cell-slot>` 包含自定义组件时,在 Android 上有性能问题
......
......@@ -16,7 +16,7 @@
|scroll-left |Number | |设置横向滚动条位置 | |
|scroll-into-view |String | |值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素 | |
|scroll-with-animation |Boolean |false |在设置滚动条位置时使用动画过渡 | |
|enable-back-to-top |Boolean |false |iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向 |微信小程序 |
|enable-back-to-top |Boolean |false |iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向 |app-nvue,微信小程序 |
|show-scrollbar |Boolean |false |控制是否出现滚动条| App-nvue 2.1.5+ |
|refresher-enabled |Boolean |false |开启自定义下拉刷新|app-vue 2.5.12+,微信小程序基础库2.10.1+|
|refresher-threshold |number |45 |设置自定义下拉刷新阈值|app-vue 2.5.12+,微信小程序基础库2.10.1+|
......
......@@ -37,7 +37,7 @@
|poster-for-crawler|String||用于给搜索等场景作为视频封面展示,建议使用无播放 icon 的视频封面图,只支持网络地址|微信小程序|
|codec|String|hardware|解码器选择,hardware:硬解码(硬解码可以增加解码算力,提高视频清晰度。少部分老旧硬件可能存在兼容性问题);software:ffmpeg 软解码;|App 3.1.0+|
|http-cache|Boolean|true|是否对 http、https 视频源开启本地缓存。缓存策略:开启了此开关的视频源,在视频播放时会在本地保存缓存文件,如果本地缓存池已超过100M,在进行缓存前会清空之前的缓存(不适用于m3u8等流媒体协议)|App 3.1.0+|
|play-strategy|Number|0| 播放策略,0:普通模式,适合绝大部分视频播放场景;1:平滑播放模式(降级),增加缓冲区大小,采用open sl解码音频,避免音视频脱轨的问题,可能会降低首屏展现速度、视频帧率,出现开屏音频延迟等。 适用于高码率视频的极端场景;|App 3.1.0+|
|play-strategy|Number|0| 播放策略,0:普通模式,适合绝大部分视频播放场景;1:平滑播放模式(降级),增加缓冲区大小,采用open sl解码音频,避免音视频脱轨的问题,可能会降低首屏展现速度、视频帧率,出现开屏音频延迟等。 适用于高码率视频的极端场景;3: M3U8优化模式,增加缓冲区大小,提升视频加载速度和流畅度,可能会降低首屏展现速度。 适用于M3U8在线播放的场景 |App 3.1.0+|
|@play|EventHandle||当开始/继续播放时触发play事件|字节跳动小程序不支持|
|@pause|EventHandle||当暂停播放时触发 pause 事件|字节跳动小程序不支持|
|@ended|EventHandle||当播放到末尾时触发 ended 事件|字节跳动小程序不支持|
......
### component
渲染一个“元组件”为动态组件。依 `is` 的值,来决定哪个组件被渲染。[详见](https://cn.vuejs.org/v2/api/#component)
**平台差异说明**
|App|H5 |微信小程序 |支付宝小程序 |百度小程序 |字节跳动小程序 |QQ小程序 |快应用 |360小程序 |
|:-:|:-:|:-: |:-: |:-: |:-: |:-: |:-: |:-: |
|√ |√ |x |x |x |x |x |x |x |
### template
`uni-app` 支持在 `template` 模板中嵌套 `<template/>``<block/>`,用来进行 [列表渲染](https://uniapp.dcloud.io/vue-basics?id=listrendering)[条件渲染](https://uniapp.dcloud.io/vue-basics?id=condition)
`<template/>``<block/>` 并不是一个组件,它们仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
`<block/>` 在不同的平台表现存在一定差异,推荐统一使用 `<template/>`
**平台差异说明**
|App|H5 |微信小程序 |支付宝小程序 |百度小程序 |字节跳动小程序 |QQ小程序 |快应用 |360小程序 |
|:-:|:-:|:-: |:-: |:-: |:-: |:-: |:-: |:-: |
|√ |√ |√ |√ |√ |√ |√ |√ |√ |
**代码示例**
```html
<template>
<view>
<template v-if="test">
<view>test 为 true 时显示</view>
</template>
<template v-else>
<view>test 为 false 时显示</view>
</template>
</view>
</template>
<script>
export default {
data() {
return {
test:true
}
}
}
</script>
```
```html
<template>
<view>
<block v-for="(item,index) in list" :key="index">
<view>{{item}} - {{index}}</view>
</block>
</view>
</template>
```
### transition
`<transition>` 元素作为单个元素/组件的过渡效果。`<transition>` 只会把过渡效果应用到其包裹的内容上,而不会额外渲染 DOM 元素,也不会出现在可被检查的组件层级中。[详见](https://cn.vuejs.org/v2/api/#transition)
**平台差异说明**
|App|H5 |微信小程序 |支付宝小程序 |百度小程序 |字节跳动小程序 |QQ小程序 |快应用 |360小程序 |
|:-:|:-:|:-: |:-: |:-: |:-: |:-: |:-: |:-: |
|x |√ |x |x |x |x |x |x |x |
### transition-group
`<transition-group>` 元素作为多个元素/组件的过渡效果。`<transition-group>` 渲染一个真实的 DOM 元素。默认渲染 `<span>`,可以通过 tag attribute 配置哪个元素应该被渲染。[详见](https://cn.vuejs.org/v2/api/#transition-group)
**平台差异说明**
|App|H5 |微信小程序 |支付宝小程序 |百度小程序 |字节跳动小程序 |QQ小程序 |快应用 |360小程序 |
|:-:|:-:|:-: |:-: |:-: |:-: |:-: |:-: |:-: |
|x |√ |x |x |x |x |x |x |x |
### keep-alive
`<keep-alive>` 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 `<transition>` 相似,`<keep-alive>` 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。[详见](https://cn.vuejs.org/v2/api/#keep-alive)
**平台差异说明**
|App|H5 |微信小程序 |支付宝小程序 |百度小程序 |字节跳动小程序 |QQ小程序 |快应用 |360小程序 |
|:-:|:-:|:-: |:-: |:-: |:-: |:-: |:-: |:-: |
|x |√ |x |x |x |x |x |x |x |
### slot
`<slot>` 元素作为组件模板之中的内容分发插槽。`<slot>` 元素自身将被替换。[插槽](https://uniapp.dcloud.io/vue-components?id=%e6%8f%92%e6%a7%bd)
详细用法,请参考下面教程的链接。[通过插槽分发内容](https://cn.vuejs.org/v2/guide/components.html#%E9%80%9A%E8%BF%87%E6%8F%92%E6%A7%BD%E5%88%86%E5%8F%91%E5%86%85%E5%AE%B9)
**平台差异说明**
|App|H5 |微信小程序 |支付宝小程序 |百度小程序 |字节跳动小程序 |QQ小程序 |快应用 |360小程序 |
|:-:|:-:|:-: |:-: |:-: |:-: |:-: |:-: |:-: |
|√ |√ |√ |√ |√ |√ |√ |√ |√ |
......@@ -42,6 +42,8 @@
**App初期启动的引导轮播:** 因为是App专用,为了更好的性能,推荐使用nvue制作。参考插件市场已经封装的插件[https://ext.dcloud.net.cn/plugin?id=676](https://ext.dcloud.net.cn/plugin?id=676)
**双向https认证:** TLS 双向认证 [详情](https://ask.dcloud.net.cn/article/38981)
**iOS平台适配暗黑模式(DarkMode):**[https://ask.dcloud.net.cn/article/36995](https://ask.dcloud.net.cn/article/36995)
**原生App和uni-app混合开发:** [详见](hybrid)
......
......@@ -193,7 +193,7 @@ vue页面在App端的渲染引擎默认是系统webview(不是手机自带浏
2.自定义组件渲染差异
微信/QQ/百度/字节跳动这四家小程序,自定义组件在渲染时会比App/H5端多一级节点,在写样式时需要注意:
微信(可以使用[virtualHost](https://uniapp.dcloud.io/vue-api?id=%e5%85%b6%e4%bb%96%e9%85%8d%e7%bd%ae)配置)/QQ/百度/字节跳动这四家小程序,自定义组件在渲染时会比App/H5端多一级节点,在写样式时需要注意:
* 使用`flex`布局时,直接给自定义组件的父元素设置为`display:flex`不能影响到自定义组件内部的根节点,需要设置当前自定义组件为`display:flex`才可以。
* 在自定义组件内部设置根元素高度为100%,不能撑满自定义组件父元素。需要同时设置当前自定义组件高度为100%才可以。
......
......@@ -13,6 +13,7 @@
- iOS端支持高斯模糊,<a href="https://ask.dcloud.net.cn/article/36617#view" target="_blank">详情</a>
- 可实现区域滚动长列表+左右拖动列表+吸顶的复杂排版效果
- 优化圆角边框绘制性能
- 扩展了更多的css
......
......@@ -52,6 +52,7 @@ uni-app 已将常用的组件、JS API 封装到框架中,开发者按照 uni-
**注意:**
* 条件编译是利用注释实现的,在不同语法里注释写法不一样,js使用 ``// 注释``、css 使用 ``/* 注释 */``、vue/nvue 模板里使用 ``<!-- 注释 -->``
* 条件编译APP-PLUS包含APP-NVUE和APP-VUE,APP-PLUS-NVUE和APP-NVUE没什么区别,为了简写后面出了APP-NVUE ;
* 使用条件编译请保证`编译前``编译后`文件的正确性,比如json文件中不能有多余的逗号;
### API 的条件编译
......
#### 3.1.14.20210430-alpha
* 【uni-app】
+ App平台、小程序平台 新增 uni.getUserProfile 方法用于获取用户信息 [详情](https://uniapp.dcloud.io/api/plugins/login?id=getuserprofile)
+ App平台、H5平台 优化 progress 组件支持 duration 参数
+ App平台 优化 uni.getVideoInfo 返回信息增加 orientation、type、bitrate 属性
+ App平台 修复 3.1.10 版本引出的 uni.chooseVideo 选取视频失败的Bug
+ App-Android平台 新增 uni.request 网络请求支持 TLS 双向认证 [详情](https://ask.dcloud.net.cn/article/38981)
+ App-Android平台 修复 nvue map 组件 marker 执行移动动画时 callout 可能不会跟随的Bug [详情](https://ask.dcloud.net.cn/question/120985)
+ App-Android平台 修复 nvue video 组件在调用分享功能返回后,视频封面会消失的Bug [详情](https://ask.dcloud.net.cn/question/121364)
+ H5平台 修复 getSystemInfoSync()获取windowBottom的高度错误 [详情](https://ask.dcloud.net.cn/question/121154)
+ 小程序平台 修复 v-for 表达式包含方法时事件编译错误的Bug
+ uni-ui 优化 为依赖 uni-icons 的 ui 组件添加依赖, 导入后自动下载依赖
+ uni-ui 修复 uni-data-picker 非树形数据有 where 属性查询报错的问题
+ uni-ui 新增 uni-datetime-picker 日历形式的日期时间选择
+ uni-ui 新增 uni-number-box v-model 双向绑定
+ uni-ui 修复 uni-number-box 浮点数运算不精确的Bug
+ uni-ui 修复 uni-number-box change 事件触发不正确的Bug
+ uni-ui 修复 uni-rate 布局变化后星星计算不准确的Bug
+ uni-ui 新增 uni-transition 通过方法自定义动画
+ uni-ui 新增 uni-transition custom-class 非 NVUE 平台支持自定义 class 定制样式
+ uni-ui 优化 uni-transition 动画触发逻辑,使动画更流畅
+ uni-ui 优化 uni-transition 支持单独的动画类型
+ uni-ui 优化 uni-transition 文档示例
* 【uniCloud】
+ 【重要】clientDB联表查询策略调整,请参考此文档进行进行排查并调整:[clientDB联表查询策略调整](https://ask.dcloud.net.cn/article/38966)
+ clientDB 新增 联表查询支持副表foreignKey联查,即副表字段的foreignKey指向主表,把副表数据挂在主表下面 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=st-foreign-key)
+ uniCloud本地调试插件 修复 阿里云偶发启动时多请求并发报错的Bug
* 【App插件(含5+App和uni-app的App端)】
+ 新增 一键登录 全屏模式支持在登录界面添加自定义登录按钮 [详情](https://uniapp.dcloud.io/univerify)
+ 新增 获取视频信息 getVideoInfo 支持获取画面方向 orientation、视频格式 type、视频码率 bitrate [文档](https://www.html5plus.org/doc/zh_cn/io.html#plus.io.VideoInfo)
+ Android平台 优化 原生模板隐私政策提示框逻辑,解决部分应用市场检测到弹出隐私政策框之前读取mac地址和应用列表的问题 [文档](https://ask.dcloud.net.cn/article/36937)
+ Android平台 更新 新浪微博分享、授权登录 SDK 为 10.10.0 版,适配支持 Android11 设备
+ Android平台 更新 高德地图 SDK 为 7.9.1 版,高德定位 SDK 为 5.3.1 版,友盟统计 SDK 为 9.3.8 版
+ Android平台 修复 腾讯云等安全检测平台报的部分高风险漏洞 [详情](https://ask.dcloud.net.cn/article/39020)
+ Android平台 修复 uni-AD 开通基础开屏广告在弱网状态可能引起崩溃的Bug
+ Android平台 修复 uni-AD 快手联盟的信息流广告可能返回高度不正确导致显示异常的Bug
+ Android平台 修复 uni原生插件在原生模板隐私政策提示框之前可能进行初始化违规读取用户数据的Bug
+ 【重要】iOS平台 优化 广告标识 IDFA 操作逻辑,适配从 iOS14.5 开始 AppStore 审核要求用户许可收集跟踪数据 [详情](https://ask.dcloud.net.cn/article/36107)
+ iOS平台 修复 一键登录 登录和其它登录按钮的默认圆角值不一致的Bug [详情](https://ask.dcloud.net.cn/question/121572)
+ iOS平台 修复 微信授权登录调用 authorize 动态传入 appid 参数不生效的Bug [详情](https://ask.dcloud.net.cn/question/121292)
#### 3.1.10.20210416-alpha
* 【uni-app】
+ App平台 新增 插屏广告 uni.createInterstitialAd [详情](https://uniapp.dcloud.net.cn/api/a-d/interstitial)
+ App平台、H5平台 新增 支持 uni.getVideoInfo 用于获取视频信息 [详情](https://uniapp.dcloud.io/api/media/video?id=getvideoinfo)
+ App平台、H5平台 优化 uni.chooseLocation 地图选点支持搜索更大范围
+ App平台、H5平台 优化 input 组件支持 cursor、selectionStart、selectionEnd 属性
+ App平台、H5平台 修复 uni.canvasToTempFilePath 参数 quality 无效的Bug [详情](https://ask.dcloud.net.cn/question/119596)
+ App平台、H5平台 修复 checkbox 组件 disabled 属性无相关样式的Bug
+ App平台 新增 支持 uni.compressVideo 用于压缩视频 [详情](https://uniapp.dcloud.io/api/media/video?id=compressvideo)
+ App平台 优化 uni.chooseVideo 支持 compressed 参数
+ App平台 优化 video 组件支持 enable-play-gesture 属性
+ App平台 修复 image 组件加载后导致其他原生组件显示错位的Bug
+ App平台 修复 多列 picker 组件未设置 value 报错的Bug [#2561](https://github.com/dcloudio/uni-app/issues/2561)
+ App平台 修复 uni.getStorageInfo 获取信息中部分 key 未包含的Bug [#2577](https://github.com/dcloudio/uni-app/issues/2577)
+ App平台 修复 uni.getSystemInfo 返回的 system 信息未包含系统名称的Bug
+ App-Android平台 修复 部分设备 input 组件设置 focus 属性为 true 时键盘收回的Bug
+ App-Android平台 修复 nvue onLoad 事件调用 plus.navigator.hideSystemNavigation 可能出现页面高度异常的Bug
+ App-Android平台 修复 nvue list 组件中加载大量图片上下滚动可能引起崩溃的Bug
+ App-Android平台 修复 nvue map 组件中多个 marker 切换后 callout 可能显示不正常的Bug [详情](https://ask.dcloud.net.cn/question/100883)
+ App-Android平台 修复 nvue map 组件与页面拖拽滚动手势冲突的Bug [详情](https://ask.dcloud.net.cn/question/120600)
+ App-Android平台 修复 nvue picker-view 组件在部分设备可能显示不正常的Bug
+ App-iOS平台 修复 nvue scroll-view 组件下添加过多子组件会有明显卡顿的Bug [详情](https://ask.dcloud.net.cn/question/118444)
+ App-iOS平台 修复 nvue map 组件 marker 标注的 label 设置 anchorY 偏移值无效的Bug [详情](https://ask.dcloud.net.cn/question/120953)
+ App-iOS平台 修复 nvue image 组件加载网络图片发送请求时没有携带 cookie 的Bug
+ H5平台 优化 uni.getSystemInfo 返回的 system 信息支持 Windows、Mac、Linux
+ H5平台 修复 picker-view-column 中的元素无法触发 click 等事件的Bug [详情](https://ask.dcloud.net.cn/question/119346)
+ H5平台 修复 innerAudio.stop 触发 onCanplay 的Bug [#2538](https://github.com/dcloudio/uni-app/issues/2538)
+ 小程序平台 修复 含有逻辑运算的复杂表达式编译后和预期不一致的Bug [详情](https://ask.dcloud.net.cn/question/118651)
+ 支付宝小程序平台 修复 默认插槽默认内容一直显示的Bug [详情](https://ask.dcloud.net.cn/question/116404)
+ uni-ui 新增 uni-data-picker 支持云端非树形表结构数据 [详情](https://ext.dcloud.net.cn/plugin?id=3796)
+ uni-ui 修复 uni-data-checkbox nvue 下无法选中的问题 [详情](https://ext.dcloud.net.cn/plugin?id=3456)
+ uni-ui 修复 uni-data-picker 根节点 parent_field 字段等于null时选择界面错乱问题 [详情](https://ext.dcloud.net.cn/plugin?id=3796)
+ uni-ui 修复 uni-file-picker 选择的文件非 file-extname 字段指定的扩展名报错的Bug [详情](https://ext.dcloud.net.cn/plugin?id=4079)
+ uni-ui 优化 uni-file-picker file-extname 字段支持字符串写法,多个扩展名需要用逗号分隔 [详情](https://ext.dcloud.net.cn/plugin?id=4079)
+ uni-ui 修复 微信小程序 nv_navigator is not defined 报错的bug
+ uni-ui 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug [详情](https://ext.dcloud.net.cn/plugin?id=29)
+ uni-ui 优化 uni-pagination PC 和 移动端适配不同的 ui [详情](https://ext.dcloud.net.cn/plugin?id=32)
+ uni升级中心 App端 新增 call-check-version.js,可用于单独检测是否有更新 [详情](https://ext.dcloud.net.cn/plugin?id=4542)
* 【uniCloud】
+ 【重要】clientDB联表查询策略调整,请参考此文档进行进行排查并调整:[clientDB联表查询策略调整](https://ask.dcloud.net.cn/article/38966)
+ unicloud-db组件 新增 loadtime 属性,替代 manual 属性 [详情](https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=props)
+ unicloud-db组件 新增 foreignKey 属性,用于存在多个foreignKey关系时指定要使用的foreignKey [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=lookup-foreign-key)
+ uniCloud.mixinDataCom 新增 foreignKey 属性,用途同上 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=lookup-foreign-key)
+ uni-id 修复 3.0.7 版本引出的多个用户访问时可能出现30201报错的Bug
+ uni-id 新增 bindMobile 接口支持通过一键登录的方式绑定 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=bind-mobile)
+ uni-id 调整 bindTokenToDevice 选项默认值改为 false,即默认不再与设备绑定,方便多设备登录
+ 修复 uniCloud.chooseAndUploadFile 在iOS微信小程序真机无法唤起选择文件的Bug
+ uniCloud admin 优化错误提示、键盘响应等众多细节,更新uni-id等众多依赖 [详情](https://ext.dcloud.net.cn/plugin?id=3268)
* 【App插件(含5+App和uni-app的App端)】
+ 新增 uni-AD支持插屏广告 [规范](https://www.html5plus.org/doc/zh_cn/ad.html#plus.ad.createInterstitialAd)
+ 更新 uni-AD 腾讯优量汇SDK iOS为 4.12.4 版,穿山甲SDK 为 3.5.5.0 版;快手联盟SDK Android为 3.3.8 版
+ 新增 离线打包支持 AppKey 管理 [文档](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/appkey)
+ 新增 压缩视频支持 filename 属性设置压缩后文件保存路径功能 [规范](https://www.html5plus.org/doc/zh_cn/zip.html#plus.zip.CompressVideoOptions)
+ 优化 一键登录 未通过审核时云端打包后调用API返回 -7 错误 [规范](https://uniapp.dcloud.io/univerify?id=%e9%94%99%e8%af%af%e7%a0%81)
+ 修复 一键登录 授权界面显示后,调用原生模态窗口无法正常显示的Bug
+ 修复 存在开屏广告时 splashclosed 事件可能在启动界面关闭前触发的Bug
+ Android平台 更新 公共测试证书,解决某些检测机构报病毒的问题 [文档](https://ask.dcloud.net.cn/article/36522)
+ Android平台 更新 gif图片库 android-gif-drawable 为 1.2.23 版,解决安全检测报存在远程代码执行漏洞的问题
+ Android平台 修复 申请权限被用户拒绝后可能无法再次正常申请权限的Bug [详情](https://ask.dcloud.net.cn/question/120747)
+ Android平台 修复 UniPush个推模块过度申请权限的Bug [详情](https://ask.dcloud.net.cn/question/119240)
+ Android平台 修复 视频播放控件 播放 http/https 地址视频的 cookie 与 X5 内核 webview 页面没有同步共享的Bug
+ Android平台 修复 一键登录 在部分设备上服务协议文本字体显示过大的Bug
+ Android平台 修复 一键登录 显示和关闭授权界面动画时间过长的Bug
+ Android平台 修复 Downloader 下载较大文件时可能引起页面无法更新的Bug
+ Android平台 修复 部分华为手机调用相机录像成功后无法找到视频文件的Bug
+ iOS平台 修复 uni-AD 仅开通增强开屏广告可能出现无法关闭spalsh页面的Bug
+ iOS平台 修复 Apple应用内支付 IAP 某些情况丢单无法恢复的Bug [文档](https://ask.dcloud.net.cn/article/497)
+ iOS平台 修复 应用覆盖安装后可能出现启动白屏的Bug
+ iOS平台 修复 从本地相册选择保存在 iCloud 的视频在下载失败时可能引起崩溃的Bug
+ iOS平台 修复 从本地相册选择gif图片预览时不能播放的Bug
+ iOS平台 修复 在 iPhone12 系列设备未适配底部安全区域的Bug [详情](https://ask.dcloud.net.cn/question/119291)
+ iOS平台 修复 视频播放控件 播放 http/https 地址视频没有同步共享 cookie 的Bug
+ iOS平台 修复 视频播放控件 VideoPlayer 播放某些视频显示方向可能不正确的Bug
#### 3.1.8.20210407-alpha
* 【uni-app】
+ App-Android平台 修复 3.1.6 版本引出的 nvue scroll-view组件设置 scroll-x 为 true 时可能引起闪退的Bug [详情](https://ask.dcloud.net.cn/question/119858)
+ App-iOS平台 修复 picker 组件部分情况下显示异常的Bug [详情](https://ask.dcloud.net.cn/question/119591)
* 【App插件(含5+App和uni-app的App端)】
+ Android平台 修复 uni-AD 激励视频播放超过30秒的穿山甲广告点击跳过按钮 onClose 回调中 isEnd 属性值为 false 的Bug
+ iOS平台 修复 一键登录 授权登录界面使用浅色背景可能看不到 loading 显示效果的Bug
* 【uniCloud】
+ 新增 [uni-upgrade-center](https://uniapp.dcloud.io/uniCloud/upgrade-center),提供了简单、易用、统一的App管理、App版本管理、安装包发布管理,升级检测更新管理。
+ uniCloud本地调试插件 修复 3.1.5 版本引出的腾讯云连接本地云函数运行一段时间后报错的Bug [详情](https://ask.dcloud.net.cn/question/119089)
+ 阿里云 新增 支持对云函数设置单实例并发度 [详情](https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=concurrency)
+ 阿里云 新增 支持TTL索引 [详情](https://uniapp.dcloud.net.cn/uniCloud/db-index?ttl)
#### 3.1.6.20210318-alpha
* 【uni-app】
+ 百度小程序平台 修复 使用基础库 3.260+ 时,复杂表达式不显示的Bug [详情](https://ask.dcloud.net.cn/question/118213)
......
#### 3.1.12.20210428
* 【uni-app】
+ App平台 修复 3.1.11 版本引出的 uni.chooseVideo 选取视频失败的Bug
+ App-Android平台 修复 3.1.11 版本引出的 nvue 页面在项目配置 nvueCompiler 为 weex 时显示不正常的Bug [详情](https://ask.dcloud.net.cn/question/121905)
+ App-iOS平台 修复 3.1.11 版本引起的 web-view 组件中 video 标签无法内联播放的Bug [详情](https://ask.dcloud.net.cn/question/121996)
+ uni-ui 优化 为依赖 uni-icons 的 ui 组件添加依赖, 导入后自动下载依赖
+ uni-ui 修复 uni-data-picker 非树形数据有 where 属性查询报错的问题
+ uni-ui 新增 uni-datetime-picker 日历形式日期时间选择
+ uni-ui 新增 uni-number-box v-model 双向绑定
+ uni-ui 修复 uni-number-box 浮点数运算不精确的 bug
+ uni-ui 修复 uni-number-box change 事件触发不正确的 bug
+ uni-ui 修复 uni-rate 布局变化后 uni-rate 星星计算不准确的 bug
+ uni-ui 新增 uni-transition 通过方法自定义动画
+ uni-ui 新增 uni-transition custom-class 非 NVUE 平台支持自定义 class 定制样式
+ uni-ui 优化 uni-transition 动画触发逻辑,使动画更流畅
+ uni-ui 优化 uni-transition 支持单独的动画类型
+ uni-ui 优化 uni-transition 文档示例
* 【uniCloud】
+ 【重要】clientDB联表查询策略调整,请参考此文档进行进行排查并调整:[clientDB联表查询策略调整](https://ask.dcloud.net.cn/article/38966)
+ clientDB 新增 联表查询支持副表foreignKey联查,即副表字段的foreignKey指向主表,把副表数据挂在主表下面 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=st-foreign-key)
+ uniCloud本地调试插件 修复 阿里云偶发启动时多请求并发报错的Bug
* 【App插件(含5+App和uni-app的App端)】
+ Android平台 修复 uni-AD 快手联盟的信息流广告可能返回高度不正确导致显示异常的Bug
#### 3.1.11.20210423
* 【uni-app】
+ App平台 新增 插屏广告 uni.createInterstitialAd [详情](https://uniapp.dcloud.net.cn/api/a-d/interstitial)
+ App平台、H5平台 新增 支持 uni.getVideoInfo 用于获取视频信息 [详情](https://uniapp.dcloud.io/api/media/video?id=getvideoinfo)
+ App平台、H5平台 优化 uni.chooseLocation 地图选点支持搜索更大范围
+ App平台、H5平台 优化 input 组件支持 cursor、selectionStart、selectionEnd 属性
+ App平台、H5平台 修复 uni.canvasToTempFilePath 参数 quality 无效的Bug [详情](https://ask.dcloud.net.cn/question/119596)
+ App平台、H5平台 修复 checkbox 组件 disabled 属性无相关样式的Bug
+ App平台 新增 支持 uni.compressVideo 用于压缩视频 [详情](https://uniapp.dcloud.io/api/media/video?id=compressvideo)
+ App平台 优化 uni.chooseVideo 支持 compressed 参数
+ App平台 优化 video 组件支持 enable-play-gesture 属性
+ App平台 修复 image 组件加载后导致其他原生组件显示错位的Bug
+ App平台 修复 多列 picker 组件未设置 value 报错的Bug [#2561](https://github.com/dcloudio/uni-app/issues/2561)
+ App平台 修复 uni.getStorageInfo 获取信息中部分 key 未包含的Bug [#2577](https://github.com/dcloudio/uni-app/issues/2577)
+ App平台 修复 uni.getSystemInfo 返回的 system 信息未包含系统名称的Bug
+ App-Android平台 修复 部分设备 input 组件设置 focus 属性为 true 时键盘收回的Bug
+ App-Android平台 修复 nvue onLoad 事件调用 plus.navigator.hideSystemNavigation 可能出现页面高度异常的Bug
+ App-Android平台 修复 nvue list 组件中加载大量图片上下滚动可能引起崩溃的Bug
+ App-Android平台 修复 nvue map 组件中多个 marker 切换后 callout 可能显示不正常的Bug [详情](https://ask.dcloud.net.cn/question/100883)
+ App-Android平台 修复 nvue map 组件 marker 执行移动动画时 callout 可能不会跟随的Bug [详情](https://ask.dcloud.net.cn/question/120985)
+ App-Android平台 修复 nvue map 组件与页面拖拽滚动手势冲突的Bug [详情](https://ask.dcloud.net.cn/question/120600)
+ App-Android平台 修复 nvue picker-view 组件在部分设备可能显示不正常的Bug
+ App-iOS平台 修复 nvue map 组件 marker 标注的 label 设置 anchorY 偏移值无效的Bug [详情](https://ask.dcloud.net.cn/question/120953)
+ H5平台 优化 uni.getSystemInfo 返回的 system 信息支持 Windows、Mac、Linux
+ H5平台 修复 picker-view-column 中的元素无法触发 click 等事件的Bug [详情](https://ask.dcloud.net.cn/question/119346)
+ H5平台 修复 innerAudio.stop 触发 onCanplay 的Bug [#2538](https://github.com/dcloudio/uni-app/issues/2538)
+ 小程序平台 修复 含有逻辑运算的复杂表达式编译后和预期不一致的Bug [详情](https://ask.dcloud.net.cn/question/118651)
+ 支付宝小程序平台 修复 默认插槽默认内容一直显示的Bug [详情](https://ask.dcloud.net.cn/question/116404)
+ uni-ui 新增 uni-data-picker 支持云端非树形表结构数据 [详情](https://ext.dcloud.net.cn/plugin?id=3796)
+ uni-ui 修复 uni-data-checkbox nvue 下无法选中的问题 [详情](https://ext.dcloud.net.cn/plugin?id=3456)
+ uni-ui 修复 uni-data-picker 根节点 parent_field 字段等于null时选择界面错乱问题 [详情](https://ext.dcloud.net.cn/plugin?id=3796)
+ uni-ui 修复 uni-file-picker 选择的文件非 file-extname 字段指定的扩展名报错的Bug [详情](https://ext.dcloud.net.cn/plugin?id=4079)
+ uni-ui 优化 uni-file-picker file-extname 字段支持字符串写法,多个扩展名需要用逗号分隔 [详情](https://ext.dcloud.net.cn/plugin?id=4079)
+ uni-ui 修复 微信小程序 nv_navigator is not defined 报错的bug
+ uni-ui 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug [详情](https://ext.dcloud.net.cn/plugin?id=29)
+ uni-ui 优化 uni-pagination PC 和 移动端适配不同的 ui [详情](https://ext.dcloud.net.cn/plugin?id=32)
+ uni升级中心 App端 新增 call-check-version.js,可用于单独检测是否有更新 [详情](https://ext.dcloud.net.cn/plugin?id=4542)
* 【uniCloud】
+ 【重要】clientDB联表查询策略调整,请参考此文档进行进行排查并调整:[clientDB联表查询策略调整](https://ask.dcloud.net.cn/article/38966)
+ unicloud-db组件 新增 loadtime 属性,替代 manual 属性 [详情](https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=props)
+ unicloud-db组件 新增 foreignKey 属性,用于存在多个foreignKey关系时指定要使用的foreignKey [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=lookup-foreign-key)
+ uniCloud.mixinDataCom 新增 foreignKey 属性,用途同上 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=lookup-foreign-key)
+ uni-id 修复 3.0.7 版本引出的多个用户访问时可能出现30201报错的Bug
+ uni-id 新增 bindMobile 接口支持通过一键登录的方式绑定 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=bind-mobile)
+ uni-id 调整 bindTokenToDevice 选项默认值改为 false,即默认不再与设备绑定,方便多设备登录
+ uni-id 调整 默认对用户名邮箱去除两端空格、忽略大小写 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=case-sensitive)
+ 修复 uniCloud.chooseAndUploadFile 在iOS微信小程序真机无法唤起选择文件的Bug
+ uniCloud admin 优化错误提示、键盘响应等众多细节,更新uni-id等众多依赖 [详情](https://ext.dcloud.net.cn/plugin?id=3268)
* 【App插件(含5+App和uni-app的App端)】
+ 新增 uni-AD支持插屏广告 [规范](https://www.html5plus.org/doc/zh_cn/ad.html#plus.ad.createInterstitialAd)
+ 更新 uni-AD 腾讯优量汇SDK iOS为 4.12.4 版,穿山甲SDK 为 3.5.5.0 版;快手联盟SDK Android为 3.3.8 版
+ 新增 离线打包支持 AppKey 管理 [文档](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/appkey)
+ 新增 压缩视频支持 filename 属性设置压缩后文件保存路径功能 [规范](https://www.html5plus.org/doc/zh_cn/zip.html#plus.zip.CompressVideoOptions)
+ 优化 一键登录 未通过审核时云端打包后调用API返回 -7 错误 [规范](https://uniapp.dcloud.io/univerify?id=%e9%94%99%e8%af%af%e7%a0%81)
+ 修复 一键登录 授权界面显示后,调用原生模态窗口无法正常显示的Bug
+ 修复 存在开屏广告时 splashclosed 事件可能在启动界面关闭前触发的Bug
+ Android平台 优化 原生模板隐私政策提示框逻辑,解决部分应用市场检测到弹出隐私政策框之前读取mac地址和应用列表的问题 [文档](https://ask.dcloud.net.cn/article/36937)
+ Android平台 更新 公共测试证书,解决某些检测机构报病毒的问题 [文档](https://ask.dcloud.net.cn/article/36522)
+ Android平台 更新 gif图片库 android-gif-drawable 为 1.2.23 版,解决安全检测报存在远程代码执行漏洞的问题
+ Android平台 修复 uni-AD 开通基础开屏广告在弱网状态可能引起崩溃的Bug
+ Android平台 修复 UniPush个推模块过度申请权限的Bug [详情](https://ask.dcloud.net.cn/question/119240)
+ Android平台 修复 视频播放控件 播放 http/https 地址视频的 cookie 与 X5 内核 webview 页面没有同步共享的Bug
+ Android平台 修复 一键登录 在部分设备上服务协议文本字体显示过大的Bug
+ Android平台 修复 一键登录 显示和关闭授权界面动画时间过长的Bug
+ Android平台 修复 Downloader 下载较大文件时可能引起页面无法更新的Bug
+ Android平台 修复 部分华为手机调用相机录像成功后无法找到视频文件的Bug
+ iOS平台 修复 一键登录 登录和其它登录按钮的默认圆角值不一致的Bug [详情](https://ask.dcloud.net.cn/question/121572)
+ iOS平台 修复 Apple应用内支付 IAP 某些情况丢单无法恢复的Bug [文档](https://ask.dcloud.net.cn/article/497)
+ iOS平台 修复 从本地相册选择保存在 iCloud 的视频在下载失败时可能引起崩溃的Bug
+ iOS平台 修复 从本地相册选择gif图片预览时不能播放的Bug
+ iOS平台 修复 视频播放控件 播放 http/https 地址视频没有同步共享 cookie 的Bug
#### 3.1.9.20210413
* 【uni-app】
+ App-iOS平台 修复 nvue image 组件加载网络图片发送请求时没有携带 cookie 的Bug
* 【App插件(含5+App和uni-app的App端)】
+ Android平台 修复 申请权限被用户拒绝后可能无法再次正常申请权限的Bug [详情](https://ask.dcloud.net.cn/question/120747)
+ iOS平台 修复 uni-AD 仅开通增强开屏广告可能出现无法关闭spalsh页面的Bug
+ iOS平台 修复 应用覆盖安装后可能出现启动白屏的Bug
* 【uniCloud】
+ 新增 [schema2code HBuilderX插件](https://ext.dcloud.net.cn/plugin?id=4684),对项目下的schema文件点右键,快速生成数据的增删改查页面。[详情](https://uniapp.dcloud.net.cn/uniCloud/schema?id=autocode)
#### 3.1.8.20210406
* 【uniCloud】
+ 新增 [uni-upgrade-center](https://uniapp.dcloud.io/uniCloud/upgrade-center),提供了简单、易用、统一的App管理、App版本管理、安装包发布管理,升级检测更新管理。
+ uniCloud本地调试插件 修复 3.1.5 版本引出的腾讯云连接本地云函数运行一段时间后报错的Bug [详情](https://ask.dcloud.net.cn/question/119089)
+ 阿里云 新增 支持对云函数设置单实例并发度,减少冷启动概率 [详情](https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=concurrency)
+ 阿里云 新增 支持TTL索引,自动删除临时数据 [详情](https://uniapp.dcloud.net.cn/uniCloud/db-index?ttl)
* 【App插件(含5+App和uni-app的App端)】
+ Android平台 修复 uni-AD 激励视频播放超过30秒的穿山甲广告点击跳过按钮 onClose 回调中 isEnd 属性值为 false 的Bug
#### 3.1.7.20210330
* 【uni-app】
+ App-Android平台 修复 3.1.6 版本引出的 nvue scroll-view组件设置 scroll-x 为 true 时可能引起闪退的Bug [详情](https://ask.dcloud.net.cn/question/119858)
+ App-iOS平台 修复 picker 组件部分情况下显示异常的Bug [详情](https://ask.dcloud.net.cn/question/119591)
* 【App插件(含5+App和uni-app的App端)】
+ iOS平台 修复 一键登录 授权登录界面使用浅色背景可能看不到 loading 显示效果的Bug
#### 3.1.6.20210326
* 【uni-app】
+ App平台、H5平台 优化 uni.showModal、uni.showActionSheet 等 API 内置国际化支持 [详情](https://uniapp.dcloud.io/collocation/i18n)
......
......@@ -8,11 +8,17 @@
- 对于程序员,从此你又get一个新技能,用熟悉的js,轻松搞定前后台整体业务。
- 对于开发商:
1. 开发成本大幅下降、开发效率大幅提升、上线和迭代速度大幅提速;
2. 如果你是新创公司,将无需雇佣php或java等服务器工程师,每年至少节省几十万;
2. 如果你是新创公司,将无需雇佣php或java等服务器工程师,每年至少节省几十万;
3. 如果你已拥有掌握php和js的全栈,那么改用新的技术栈,一样可以大幅提升开发效率、降低成本;
4. 你只需专注于你的业务,其他什么服务器运维、弹性扩容、大并发承载、防DDoS攻击,全都不需要操心;
5. 除了开发成本,云资源租用成本也将大幅下降
5. 如果不发布H5版,你将不需要购买备案域名。小程序和App可以免域名使用服务器;
5. 除了开发成本,云资源租用成本也将大幅下降
6. 如果不发布H5版,你将不需要购买备案域名。小程序和App可以免域名使用服务器;
### 看视频,只需25分钟,快速入门uniCloud
- [腾讯课堂视频教程](https://ke.qq.com/course/3416784?taid=11123338234831568&tuin=4025c735)
### uniCloud是什么和不是什么
......@@ -26,11 +32,6 @@ uniCloud是DCloud在阿里云和腾讯云的serverless服务上封装而成的
开发时虽使用DCloud的工具,但应用上线时,手机端是直连阿里云或腾讯云的serverless,不经由DCloud的服务器。
<video style="width:50vw;height:30vw;margin-bottom:20px;" id="video" preload="none" controls="controls" poster="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/e5da48fa-33c1-4379-8927-65edc6d05d5f.mp4?x-oss-process=video/snapshot,t_1000,f_jpg" src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/e5da48fa-33c1-4379-8927-65edc6d05d5f.mp4"></video>
- [更多视频教程](https://ke.qq.com/course/3416784?taid=11123338234831568&tuin=4025c735)
### 什么是serverless?
serverless是目前很火的概念,它是下一代云技术,是真正的“云”。
......@@ -70,7 +71,7 @@ serverless在国外兴起,但国内的发展速度已经超过了国外。微
### uniCloud为何可降低云服务租用成本
1. 传统云服务的租用,按占用的硬件资源的上限值+固定时长来租用。
1传统云服务的租用,按占用的硬件资源的上限值+固定时长来租用。
选择CPU和内存的配置,不到满配时,资源是浪费的,接近满配就需要立即扩容新的配置。
......@@ -84,7 +85,7 @@ serverless不是传统云,它不需要开发者选择CPU和内存配置,也
从技术原理上serverless就有明显成本优势,所以租用serverless比租用传统云要便宜的多。
2. 没有名目繁多的收费项
2没有名目繁多的收费项
在传统云的世界里,有大量的收费产品。
......@@ -98,7 +99,7 @@ serverless不是传统云,它不需要开发者选择CPU和内存配置,也
展开说下uniCloud为什么不用买高防也不害怕DDoS:由于阿里云和腾讯云的serverless有巨大的资源池,且serverless没有固定ip,云函数使用的是阿里云和腾讯云的自有域名,前端网页托管在cdn上,DDoS攻击者打不起、也打不挂uniCloud。
3. 云厂商的促销补贴
3云厂商的促销补贴
目前阿里云为uniCloud提供了纯免费的云资源,不但云函数、云数据库免费,连存储和cdn都免费。
......
......@@ -293,6 +293,28 @@ admin 提供了两个内置方法,方便在页面中鉴定登录用户权限
</template>
```
#### 给系统创建多个登录账户并设置不同的权限@mutiladmin
下面以增加一个普通成员的角色为例,该角色的用户登录admin系统后只能看用户表数据,不能改动数据。
##### 1. 先用admin账户登陆admin系统。
- admin示例项目地址:[https://unicloudadmindemo.dcloud.net.cn/#/pages/login/login](https://unicloudadmindemo.dcloud.net.cn/#/pages/login/login)
- 体验账号:admin 密码:123456
##### 2. 创建权限。在uniCloud admin左侧菜单的权限管理,新增权限“查询信息”,标识为“read”
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/4f4333ed-2a54-4e98-85b6-ec5095a43805.jpg)
##### 3. 创建角色。在左侧菜单的角色管理里,新增角色“普通成员”,标识为“member”,绑定上面的“查询信息”权限
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/f3b563b3-3e86-4823-9373-64c9bebdd51c.jpg)
##### 4. 创建账户并赋予角色。在左侧菜单的用户管理里,添加用户“张三”,然后给用户赋予角色“普通成员”
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/16f173a2-e889-404b-b509-346d3b929a0d.jpg)
##### 5.如果你退出账户,登陆刚刚创建的账户张三。我们发现会提示:该账户没有被赋予登录admin系统的权限, 请联系系统管理员绑定角色赋权限。因为:你登陆的账户没有访问任何admin系统菜单的权限,所以不能访问admin系统。
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/0b627d45-da68-435b-995b-a191e7330624.jpg)
##### 6.设置有查询信息权限的人,拥有访问admin系统菜单"用户管理"的权限。在左侧菜单的菜单管理里,找到菜单“用户管理”,点修改,在权限列表里勾选“查询信息”,也就是有查询信息权限的人,可以看到本菜单
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/74c48248-d8ae-4427-9abb-8a6c5d54c53d.jpg)
##### 7.这时你用账户“张三”登陆,就能进入到admin系统。但你会看到如下图提示“权限校验未通过”。因为刚刚仅为该用户赋予了访问菜单的权限。还未赋予访问uni-id-users表的阅读权限
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/37d1604e-bcb1-4096-a373-90397b9a96c0.jpg)
##### 8. 需要在hbuilderx中将表uni-id-users的schema文件中设置新角色的权限,将permission下的read节点配置为`"read": "'read' in auth.permission"`,并上传到云端。当然这在示例项目不能实现,需要你自己搭建admin系统,重复以上步骤,[点此下载uniCloud admin](https://ext.dcloud.net.cn/plugin?id=3268)
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/81e38081-9507-4e00-bafd-7dab26e9a119.png)
##### 9.此时你再刷新页面即可访问用户管理的数据列表
### 新增页面
新增页面可以自己开发页面,也可以从插件市场下载插件。页面如需添加菜单,参见上文的[菜单管理](#静态菜单和动态菜单)
......
......@@ -210,7 +210,10 @@ let res = await collection.doc('doc-id').set({
name: "Hey"
});
```
**注意**
- 自动生成的_id是自增的,后创建的记录的_id总是大于先生成的_id
## 查询文档
......
......@@ -21,36 +21,37 @@ exports.main = async (event, context) => {
'use strict';
exports.main = async (event, context) => {
//event为客户端上传的参数
...
//...
//context中可获取客户端调用的上下文
let clientIP = context.CLIENTIP // 客户端ip信息
let clientUA = context.CLIENTUA // 客户端user-agent
let spaceInfo = context.SPACEINFO // 当前环境信息 {spaceId:'xxx',provider:'tencent'}
// 以下四个属性只有使用uni-app以callFunction方式调用才能获取
let os = context.OS //客户端操作系统,返回值:android、ios 等
let platform = context.PLATFORM //运行平台,返回值为 mp-weixin、app-plus等
let appid = context.APPID // manifest.json中配置的appid
let clientIP = context.CLIENTIP // 客户端ip信息
let clientUA = context.CLIENTUA // 客户端user-agent
let deviceId = context.DEVICEID // 客户端标识,新增于HBuilderX 3.1.0,同uni-app客户端getSystemInfo接口获取的deviceId
let spaceInfo = context.SPACEINFO // 当前环境信息 {spaceId:'xxx',provider:'tencent'}
... //其它业务代码
//... //其它业务代码
}
```
云函数url化的场景下无法获取`context.OS``context.PLATFORM``context.APPID``context.CLIENTUUID`
>在云函数URL化的场景无法获取客户端平台信息,可以在调用依赖客户端平台的接口接口之前(推荐在云函数入口)通过修改context.PLATFORM手动传入客户端平台信息供其他插件(如:uni-id)使用
例:
```js
```
云函数url化的场景下无法获取`context.OS``context.PLATFORM``context.APPID``context.CLIENTUUID`
>在云函数URL化的场景无法获取客户端平台信息,可以在调用依赖客户端平台的接口接口之前(推荐在云函数入口)通过修改context.PLATFORM手动传入客户端平台信息供其他插件(如:uni-id)使用
例:
```js
exports.main = async (event, context) => {
context.PLATFORM = 'app-plus'
}
}
```
云函数中如果要使用其他服务(比如mysql数据库、redis等),可以按照nodejs的写法即可。但注意这些非uniCloud数据库和云函数运行环境不在一起,访问速度受影响。
**注意事项**
- 服务商为阿里云时,暂不可使用相对路径读取文件(比如`fs.readFileSync('./info.txt')`),可以使用绝对路径`fs.readFileSync(path.resolve(__dirname,'./info.txt'))`
- 服务商为阿里云时,暂不可使用相对路径读取文件(比如`fs.readFileSync('./info.txt')`),可以使用绝对路径`fs.readFileSync(path.resolve(__dirname,'./info.txt'))`
- event大小不可超过100kb
## API列表
......@@ -69,7 +70,52 @@ exports.main = async (event, context) => {
|uniCloud.logger |云函数中打印日志到uniCloud日志记录系统(非HBuilderX控制台)[详情](uniCloud/cf-logger) |
|uniCloud.sendSms() |发送短信 [详见](uniCloud/send-sms.md) |
## 特殊属性
**注意:下面所有的“客户端”均是相对于云函数而言,如果你使用自己的服务器调用云函数此时客户端是指你的服务器**
### 获取客户端IP@clientip
```js
'use strict';
exports.main = async (event, context) => {
let clientIP = context.CLIENTIP // 客户端ip信息
}
```
### 获取客户端user-agent@client-user-agent
```js
'use strict';
exports.main = async (event, context) => {
let clientUA = context.CLIENTUA // 客户端user-agent信息
}
```
### 获取服务空间信息@context-space-info
```js
'use strict';
exports.main = async (event, context) => {
let spaceInfo = context.SPACEINFO // 当前环境信息 {spaceId:'xxx',provider:'tencent'}
}
```
### 其他客户端信息@client-info
**以下四个属性只有使用uni-app以callFunction方式调用才能获取**
```js
'use strict';
exports.main = async (event, context) => {
let os = context.OS //客户端操作系统,返回值:android、ios 等
let platform = context.PLATFORM //运行平台,返回值为 mp-weixin、app-plus等
let appid = context.APPID // manifest.json中配置的appid
let deviceId = context.DEVICEID // 客户端标识,新增于HBuilderX 3.1.0,同uni-app客户端getSystemInfo接口获取的deviceId
}
```
## 访问数据库
云函数中支持访问本服务空间下的数据库,调用方式详见[规范](uniCloud/cf-database.md)
......@@ -131,30 +177,30 @@ const res = await uniCloud.httpclient.request(apiUrl, {
method: 'POST',
data: {
test: 'testValue'
},
},
contentType: 'json', // 指定以application/json发送data内的数据
dataType: 'json' // 指定返回值为json格式,自动进行parse
})
console.log(res)
```
返回数据结构如下
```js
{
"data": {"name": "DCloud"}, // 响应内容
"status": 200, // 状态码
"headers": { // 响应头,仅作示例,不同服务器返回的有差异
"date": "Tue, 29 Dec 2020 08:10:30 GMT",
"content-type": "application/json",
"content-length": "276",
"connection": "keep-alive",
"server": "gunicorn/19.9.0",
"access-control-allow-origin": "*",
"access-control-allow-credentials": "true"
}
}
```
返回数据结构如下
```js
{
"data": {"name": "DCloud"}, // 响应内容
"status": 200, // 状态码
"headers": { // 响应头,仅作示例,不同服务器返回的有差异
"date": "Tue, 29 Dec 2020 08:10:30 GMT",
"content-type": "application/json",
"content-length": "276",
"connection": "keep-alive",
"server": "gunicorn/19.9.0",
"access-control-allow-origin": "*",
"access-control-allow-credentials": "true"
}
}
```
## 使用npm
......@@ -212,7 +258,7 @@ uniCloud.callFunction({
## 云函数中调用云函数@callbyfunction
用法同客户端调用云函数,不支持callback形式。**云函数本地运行时使用callFunction会调用云端的云函数而不是本地云函数**
用法同客户端调用云函数,不支持callback形式。**云函数本地运行时使用callFunction会调用云端的云函数而不是本地云函数,连接本地云函数调试时云函数内的callFunction会调用本地云函数**
#### 请求参数
......@@ -249,12 +295,12 @@ let callFunctionResult = await uniCloud.callFunction({
- 使用路由框架,在一个云函数内通过控制器、路由的方式编写服务器接口,控制更灵活。插件市场有很多这类插件,[详见](https://ext.dcloud.net.cn/search?q=%E8%B7%AF%E7%94%B1&orderBy=WeekDownload&cat1=7)
## 云函数配置
### 超时时间
**注意**
- 目前阿里云的超时时间和腾讯云有区别,如果在阿里云云函数运行超过10秒那么客户端没法同步接收返回结果,但是云函数仍会运行到配置的超时时间。腾讯云在云函数运行到配置的超时时间之前客户端都是可以收到返回结果的。
### 超时时间
**注意**
- 目前阿里云的超时时间和腾讯云有区别,如果在阿里云云函数运行超过10秒那么客户端没法同步接收返回结果,但是云函数仍会运行到配置的超时时间。腾讯云在云函数运行到配置的超时时间之前客户端都是可以收到返回结果的。
### 固定出口IP@eip
......@@ -271,6 +317,67 @@ serverless默认是没有固定的服务器IP的,因为有很多服务器在
- 同一个服务空间内所有开启固定出口IP的云函数使用的是同一个IP。
- 如果你是免费版升配到付费版,开启`固定IP`功能后,会导致付费版到期无法自动降级到免费版,请注意按时续费
### 单实例多并发@concurrency
> 仅阿里云支持
默认情况下云函数仅支持单实例单并发,即同一时间一个实例仅可为一个用户服务(不同用户同一时间访问会被分派到不同实例进行处理)。通过修改云函数单实例并发度,可以修改云函数同一时间最多能处理多少请求。
假设同时有3个请求需要处理,当实例并发度设置为1时,需要创建3个实例来处理这3个请求,每个实例分别处理1个请求。而每开启一个实例都会引发云函数冷启动;当云函数的实例并发度设置为10时(即1个实例可以同时处理10个请求),只需要创建1个实例就能处理这3个请求。这样后面2个并发请求不会造成云函数的冷启动。
**开启方式**
云函数详情页面配置单实例并发度即可,支持1-100之间的数值
**效果**
- 有效减少并发请求时云函数冷启动次数
**使用注意**
- 云函数内存使用量会随着并发量增大而增加
- 如果并发的不同请求对全局变量同时进行读写会污染全局变量,可能会导致意想不到的后果,开启单实例多并发后请不要编写修改全局变量的代码,除非你熟悉这种技术带来的特殊应用,比如下文进阶部分提到的ip过滤。
**适用场景**
|场景 |适用性 |理由 |
|:-: |:-: |:-: |
|函数中有较多时间在等待下游服务的响应 |适用 |等待响应一般不消耗资源,在一个实例内并发处理可以节省费用。 |
|函数中有共享状态且不能并发访问 |不适用 |例如全局变量,多请求并发执行修改共享状态可能会导致错误。 |
|单个请求的执行要消耗大量CPU及内存资源|不适用 |多请求并发执行会造成资源争抢,可能会导致内存不足(OOM)或者延时增加。|
**关于uni-id的特殊说明**
```js
// 开启单实例多并发前的uni-id用法
const uniID = require('uni-id')
exports.main = async function(event, context) {
const res = uniID.login({
// ...一些参数
})
return res
}
// 由于uni-id默认会从一个内置全局变量上获取客户端平台信息,不同请求会修改此全局变量可能造成混乱,开启单实例多并发后需要将uni-id修改为如下写法
let uniID = require('uni-id')
exports.main = async function(event, context) {
let uniIDIns = uniID.createInstance({ // 创建uni-id实例,其上方法同uniID
context: context, // 传入context防止不同请求互相影响
config: {} // 完整uni-id配置信息,使用config.json进行配置时无需传此参数
})
const res = uniIDIns.login({
// ...一些参数
})
return res
}
```
**进阶**
开启单实例多并发后的全局变量复用并非一定是坏的结果,如果你很了解此行为,也可以对此进行有效的利用
例:[ip-filter](https://ext.dcloud.net.cn/plugin?id=4619)中就利用云函数全局缓存一些ip访问信息来限制单ip访问频率,可以下载示例项目体验一下
## 云函数package.json@packagejson
HBuilderX 3.0版本之前,package.json只是一个标准的package.json,一般来说安装依赖或公共模块才需要。HBuilderX 3.0及以上版本,package.json也可以用来配置云函数。
......@@ -309,6 +416,7 @@ package.json是一个标准json文件,不可带注释。下面是一个package
```js
{
"concurrency": 10, // 单个云函数实例最大并发量,不配置的情况下默认是1
"memorySize": 256, // 函数的最大可用内存,单位MB,可选值: 128|256|512|1024|2048,默认值256
"timeout": 5, // 函数的超时时间,单位秒,默认值5。最长为60秒,阿里云在定时触发时最长可以是600秒
// triggers 字段是触发器数组,目前仅支持一个触发器,即数组只能填写一个,不可添加多个
......@@ -503,7 +611,7 @@ exports.main = async function() {
### 其它
-函数中使用的时区是 `UTC+0`,而不是 `UTC+8`,在云函数中使用时间时需特别注意
-端的云函数中使用的时区是 `UTC+0`,而不是 `UTC+8`,在云函数中使用时间时需特别注意。云函数在HBuilderX本地运行时,时区则是电脑的时区,很可能是 `UTC+8`。建议使用时间戳,可以规避时区问题
- 使用阿里云作为服务商时,暂时无法使用相对路径读取文件,如:`fs.readFileSync('./info')`,可以替换为`fs.readFileSync(path.resolve(__dirname,'./info'))`
- 阿里云目前能同步返回数据的最大超时时间为10秒,即云函数运行超过10秒时客户端会收到超时报错。如果你在uniCloud web控制台配置了10秒以上的超时时间,云函数是可以运行到10秒以上的,只是客户端无法接收到返回值,腾讯云没有此限制。
此差异已折叠。
......@@ -133,6 +133,20 @@
![地理位置索引](https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/21b31780-5fb0-11eb-bdc1-8bd33eb6adaa.jpg)
### TTL索引@ttl
ttl索引用于设置数据过期时间,并在数据过期后进行删除。
配置方式如下:
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/25187fa4-dc40-48a2-ba00-e6ad8c604c39.jpg)
**注意**
- 数据删除并非实时,mongoDB会在后台定时进行数据清理
- 启用ttl索引后仅可添加一个索引字段
- 仅支持对存储了日期类型(并非时间戳)的字段进行设置ttl索引
## 索引使用注意事项
### 唯一性限制
......
......@@ -58,7 +58,7 @@ uniCloud提供了比微信云开发更优秀的前端操作数据库方案,见
### 云开发是nodejs+改良版MongoDB组合,对比php+mysql的传统组合怎么样?
nodejs的性能于php,MongoDB的性能也优于mysql。
nodejs的性能于php,MongoDB的性能也优于mysql。
对于前端而言,MongoDB这种类json的文档数据库更加易用,且有更高的灵活性。
操作MongoDB仍然使用js的方法。
......@@ -117,6 +117,7 @@ websocket的实时特性导致serverless化比较复杂,目前曲线方案有
1. 使用clientDB可以减少遇到冷启动问题的概率
2. 非高频访问的云函数,合并到高频云函数中。有的开发者使用纯单页方式编写云函数,即在一个云函数中通过路由处理实现了整个应用的所有后台逻辑。参考[插件](https://ext.dcloud.net.cn/search?q=%E8%B7%AF%E7%94%B1&cat1=7&orderBy=UpdatedDate)
3. 非高频访问的云函数,可以通过定时任务持续运行它(注意腾讯云可以使用这个方式完全避开冷启动,而阿里云的定时任务最短周期大于资源回收周期)
4. 配置云函数的单实例多并发
### uniCloud访问速度感觉不如传统服务器?@slow
有开发者在一台单机上安装php或java,连接同电脑的mysql。然后与uniCloud比较速度,认为uniCloud偏慢。这里需要澄清如下差异:
......@@ -275,3 +276,75 @@ exports.main = async function(event){
2. 错误信息:`The root domain of your domain is reserved by another account`
当前域名有在阿里云开通全站加速相关业务(可能配置了泛域名加速),与前端网页托管冲突。可以考虑使用三级域名或去除泛域名加速改为单独配置需要加速的域名。
### 授权其他用户访问服务空间@collaborator
开发期间经常需要多人共用同一个服务空间,此时可以在[DCloud开发者中心](https://dev.dcloud.net.cn/)将特定应用及其关联的服务空间共享给协作者,详细步骤如下
1. 在开发者中心`我创建的应用`列表页面选择特定的应用
![我创建的应用](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/865a0df3-3169-48df-8b4c-8acacf1a621f.jpg)
2. 在第一步选择的应用详情页面左侧菜单点击`项目成员管理`
3. 输入协作者邮箱并点击`添加协作者按钮`,下方会出现协作者权限配置界面
![项目成员管理](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/2e59ce9b-f202-4432-954c-d6182187ef94.jpg)
4. 勾选uniCloud并点击`设置授权服务空间`,在弹出界面勾选希望此协作者访问的服务空间
![设置授权服务空间](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/b3c234a7-e514-4b14-b33d-e7322130bd7d.jpg)
5. 点击第4步弹出界面的`保存按钮`以及第3步的`保存权限设置`按钮
### 如何使用promise/async/await@promise
uniCloud客户端callFunction及数据库相关接口会返回Promise类型结果,请参考以下写法使用:
```html
// index.vue
<template>
<view class="content">
<button type="default" @click="testThen">promise+then</button>
<button type="default" @click="testAwait">async+await</button>
</view>
</template>
<script>
export default {
data() {
return {}
},
methods: {
testThen() {
uniCloud.callFunction({
name: 'test'
}).then(res => {
console.log(res)
}).catch(err => {
console.error(err)
})
},
async testAwait() {
const res = await uniCloud.callFunction({
name: 'test'
})
console.log(res)
// 如需捕获错误需使用如下写法
// try {
// const res = await uniCloud.callFunction({
// name: 'test'
// })
// console.log(res)
// } catch (err) {
// console.error(err)
// }
}
}
}
</script>
<style>
</style>
```
\ No newline at end of file
......@@ -23,7 +23,7 @@
上述数据中,每行数据表示一个用户的信息,被称之为“记录(record/doc)”。name和tel称之为“字段(field)”。而“13900000000”则是第一条记录的字段tel的值。
记录,都是一个完整的json文档,获取到记录后可以使用常规json方式操作。但集合并非json文档,集合是多个json文档的汇总,获取集合需要使用专门的API。
记录,都是一个完整的json文档,获取到记录后可以使用常规json方式操作。但集合并非json文档,集合是多个json文档的汇总,获取集合需要使用专门的API。
与关系型数据库的二维表格式不同,json文档数据库支持不同记录拥有不同的字段、支持多层嵌套数据。
......@@ -47,6 +47,8 @@ _此处仅为举例,实际业务中,登录日志单独存放在另一个集
对于初学者,如果不了解数据库设计,可以参考[opendb](https://gitee.com/dcloud/opendb),已经预置了大量常见的数据库设计。
对于不熟悉传统数据库,但掌握json的js工程师而言,uniCloud的云数据库更亲切,没有传统数据库高昂的学习成本。
在uniCloud web控制台新建表时,在下面的模板中也可以选择各种`opendb`表模板,直接创建。
**字段的值,支持以下类型:**
......@@ -64,6 +66,8 @@ _此处仅为举例,实际业务中,登录日志单独存放在另一个集
* Date:时间
* Null:相当于一个占位符,表示一个字段存在但是值为空。
DB Schema中还扩展了其他字段类型,但其实都是基本类型的扩展,比如file类型其实是一种特殊的object,而password类型是一种特殊的string类型。
uniCloud同时支持阿里云和腾讯云,它们的数据库大体相同,有细微差异。阿里云的数据库是mongoDB4.0,腾讯云则使用自研的文档型数据库(兼容mongoDB 4.0版本)。uniCloud基本抹平了不同云厂商的差异,有差异的部分会在文档中单独标注。
如果想在云函数连接其他数据库,如mysql/redis,用法和nodejs连接这些数据库是一样的。插件市场已经有人提供了插件,见下。但注意这些用法推荐用于数据导入,主业务开发不建议这么使用。因为其他服务器上的数据库和云函数环境物理上不在一起,连接会比较慢。
......@@ -113,15 +117,15 @@ const db = uniCloud.database({
## 创建一个集合/数据表@createCollection
新建的服务空间,没有一个集合。需要首先创建集合
新建的服务空间,没有数据表。需要首先创建集合/数据表
可以在uniCloud的web控制台([https://unicloud.dcloud.net.cn](https://unicloud.dcloud.net.cn))在web页面创建集合,也可以通过代码创建集合
可以在uniCloud的web控制台([https://unicloud.dcloud.net.cn](https://unicloud.dcloud.net.cn))在web页面创建数据表,也可以通过代码创建数据表
通过代码创建集合的方式,阿里云和腾讯云有差别:
通过代码创建数据表的方式,阿里云和腾讯云有差别:
- 阿里云
调用add方法,给某集合新增数据记录时,如果该集合不存在,会自动创建该集合。如下代码给table1集合新增了一条数据,如果table1不存在,会自动创建。
调用add方法,给某数据表新增数据记录时,如果该数据表不存在,会自动创建该数据表。如下代码给table1数据表新增了一条数据,如果table1不存在,会自动创建。
```js
const db = uniCloud.database();
......@@ -130,7 +134,7 @@ db.collection("table1").add({name: 'Ben'})
- 腾讯云
腾讯云提供了专门的创建集合的API,此API仅支持云函数内运行,不支持clientDB调用。
腾讯云提供了专门的创建数据表的API,此API仅支持云函数内运行,不支持clientDB调用。
```js
const db = uniCloud.database();
......@@ -138,18 +142,18 @@ db.createCollection("table1")
```
**注意**
* 如果集合已存在,腾讯云调用createCollection方法会报错
* 腾讯云调用collection的add方法不会自动创建集合,不存在的集合会报错
* 如果数据表已存在,腾讯云调用createCollection方法会报错
* 腾讯云调用collection的add方法不会自动创建数据表,不存在的数据表会报错
* 阿里云没有createCollection方法
## 集合的3个组成部分
## 集合/数据表的3个组成部分
每个集合,其实包含3个部分:
每个数据表,其实包含3个部分:
- data:数据内容
- index:数据库索引
- index:索引
- schema:数据表格式定义
在uniCloud的web控制台可以看到一个集合的3部分内容。
在uniCloud的web控制台可以看到一个数据表的3部分内容。
### 数据内容@dbdata
......@@ -157,63 +161,40 @@ data很简单,就是存放的数据记录(record)。
实际上,创建一条新记录,是不管在web控制台创建,还是通过API创建,每条记录都会自带一个`_id`字段用以作为该记录的唯一标志。
`_id`字段是每个集合默认自带且不可删除的字段。同时,它也是集合的索引。
`_id`字段是每个数据表默认自带且不可删除的字段。同时,它也是数据表的索引。
`_id`长度是12位,它是自增的,后创建的记录的`_id`总是大于先生成的`_id`。传统数据库的自然数自增字段在多物理机的大型数据库下很难保持同步,大型数据库均使用`_id`这种长度较长、不会重复且仍然保持自增规律的方式。
### 数据库索引@dbindex
所谓索引,是指在集合的众多字段中挑选一个或多个字段,让数据库引擎优先处理这些字段。设置为索引的字段,在通过该字段查询记录时可以获得更快的查询速度
所谓索引,是指在数据表的众多字段中挑选一个或多个字段,让数据库引擎优先处理这些字段。设置为索引的字段,在通过该字段查询记录时可以获得更快的查询速度。但设置过多索引也不合适,会造成数据新增和删除变慢
一个集合可以有多个字段被设为索引。
一个数据表可以有多个字段被设为索引。
索引分唯一型和非唯一型。
唯一型索引要求整个集合多个记录的该字段的值不能重复。比如`_id`就是唯一型索引。
唯一型索引要求整个数据表多个记录的该字段的值不能重复。比如`_id`就是唯一型索引。
假使有2个人都叫“张三”,那么他们在user集合里的区分就是依靠不同的`_id`来区分。
假使有2个人都叫“张三”,那么他们在user数据表里的区分就是依靠不同的`_id`来区分。
如果我们要根据name字段来查询,为了提升查询速度,此时可以把name字段设为非唯一索引。
还有“组合索引”的概念,可以把多个字段组合成一个“组合索引”。例如一个文章点赞记录明细表,设置文章id和用户id为组合索引,且将此组合索引设为唯一型索引,就可以限制同一用户对一篇文章多次点赞。
索引内容较多,还有“组合索引”、“稀疏索引”、“地理位置索引”、“TTL索引”等概念。有单独的文档详细讲述索引,另见:[数据库索引](/uniCloud/db-index)
**在web控制台添加上述索引**
![](https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/fca53140-1d91-11eb-880a-0db19f4f74bb.jpg)
**在db_init.json内添加上述索引**
```json
{
"opendb-news-article": {
"data": [],
"index":[{
"IndexName": "user_article_", // 索引名称
"MgoKeySchema": { // 索引规则
"MgoIndexKeys": [{
"Name": "user_id", // 索引字段
"Direction": "1" // 索引方向,1:ASC-升序,-1:DESC-降序,2dsphere:地理位置
},{
"Name": "article_id", // 索引字段
"Direction": "1" // 索引方向,1:ASC-升序,-1:DESC-降序,2dsphere:地理位置
}],
"MgoIsUnique": false // 索引是否唯一
}
}]
}
}
```
**注意**
- 如果记录中已经存在多个记录某字段相同的情况,那么将该字段设为唯一型索引会失败。
- 如果已经设置某字段为唯一索引,在新增和修改记录时如果该字段的值之前在其他记录已存在,会失败。
- 假如记录中不存在某个字段,则对索引字段来说其值默认为 null,如果该索引字段设为唯一型索引,则不允许存在两个或以上的该字段为null或不存在该字段的记录。
#### 稀疏索引
- 假如记录中不存在某个字段,则对索引字段来说其值默认为 null,如果该索引字段设为唯一型索引,则不允许存在两个或以上的该字段为null或不存在该字段的记录。此时需要设置稀疏索引来解决多个null重复的问题
[文档已移至](uniCloud/db-index.md?id=sparse)
### 数据表格式定义@dbschema
`DB Schema`是集合的表结构描述。描述集合有哪些字段、值域类型是什么、是否必填、数据操作权限等很多内容。
`DB Schema`是集合的表结构描述。描述数据表有哪些字段、值域类型是什么、是否必填、数据操作权限等很多内容。
因为json文档数据库的灵活性,data数据的字段可以不在schema的描述范围内。
......@@ -224,23 +205,23 @@ data很简单,就是存放的数据记录(record)。
## 获取集合/数据表对象
创建好集合后,可以通过API获取集合对象。
创建好数据表后,可以通过API获取数据表对象。
```js
const db = uniCloud.database();
// 获取名为 `table1` 集合的引用
// 获取名为 `table1` 数据表的引用
const collection = db.collection('table1');
```
**集合 Collection 的方法**
**集合/数据表 Collection 的方法**
通过 `db.collection(name)` 可以获取指定集合的引用,在集合上可以进行以下操作
通过 `db.collection(name)` 可以获取指定数据表的引用,在数据表上可以进行以下操作
| 类型 | 接口 | 说明 |
| -------- | ------- | ---------------------------------------------------------------------------------- |
| 写 | add | 新增记录(触发请求) |
| 计数 | count | 获取符合条件的记录条数 |
| 读 | get | 获取集合中的记录,如果有使用 where 语句定义查询条件,则会返回匹配结果集 (触发请求) |
| 引用 | doc | 获取对该集合中指定 id 的记录的引用 |
| 读 | get | 获取数据表中的记录,如果有使用 where 语句定义查询条件,则会返回匹配结果集 (触发请求) |
| 引用 | doc | 获取对该数据表中指定 id 的记录的引用 |
| 查询条件 | where | 通过指定条件筛选出匹配的记录,可搭配查询指令(eq, gt, in, ...)使用 |
| | skip | 跳过指定数量的文档,常用于分页,传入 offset。clientDB组件有封装好的更易用的分页,[另见](uniCloud/uni-clientdb-component) |
| | orderBy | 排序方式 |
......@@ -284,7 +265,7 @@ uniCloud数据库提供了多种数据导入导出和备份方案。
- db_init.json位置由`cloudfunctions/db_init.json`移至`uniCloud/database/db_init.json`
- schema不再放在db_init.json内,每个表都有一个单独的schema文件,比如news表对应的schema为`uniCloud/database/news.schema.json`
- schema可以在`uniCloud/database`目录上右键创建
- db_init.json文件右键初始化云数据库时依然会带上schema进行数据库的初始化,除schema外HBuilderX3.0.0以上版本使用db_init.json初始化数据库还会带上扩展校验函数,扩展校验函数位于`uniCloud/database/validateFunction`目录下,扩展校验函数文档详见:[validateFunction](https://uniapp.dcloud.net.cn/uniCloud/schema?id=validatefunction)
- `db_init.json`文件右键初始化云数据库时依然会带上schema进行数据库的初始化,除schema外HBuilderX3.0.0以上版本使用db_init.json初始化数据库还会带上扩展校验函数,扩展校验函数位于`uniCloud/database/validateFunction`目录下,扩展校验函数文档详见:[validateFunction](https://uniapp.dcloud.net.cn/uniCloud/schema?id=validatefunction)
**HBuilderX 3.0.0版本之前的db_init.json示例**
......@@ -356,6 +337,16 @@ uniCloud数据库提供了多种数据导入导出和备份方案。
- 如果表名与opendb中任意表名相同,web控制台导出时将不会带上schema和index。
- web控制台导出时默认不包括`_id`字段,在导入时,数据库插入新记录时会自动补`_id`字段。如果需要指定`_id`,需要手工补足数据。
在db_init.json内可以使用以下形式定义Date类型的数据:
```js
{
"dateObj": { // dateObj字段就是日期类型的数据
"$date": "2020-12-12T00:00:00.000Z" // ISO标准日期字符串
}
}
```
### 数据库回档备份和恢复@backup
**此功能暂时只有腾讯云支持**
......
......@@ -102,7 +102,9 @@ DCloud为开发者提供了`uni发布平台`,包括网站发布、App发布和
阿里云现已支持http强制跳转https,在上述添加界面打开对应开关即可
如果你已经有备案过的域名,直接解析过来即可;如果你要新注册域名,首先自行在网上购买,然后注意域名如果想在国内正常绑定阿里云或腾讯云,需要域名备案。这里的备案流程和传统云主机略有不同,涉及一个uniCloud没有固定ip的问题。此时可以去买花生壳的备案服务;也可以临时买一个短期固定ip,走固定ip备案。这里有开发者分享的[经验贴](https://uniapp.dcloud.io/uniCloud/cf-functions?id=eip)
**域名备案**
如果你已经有备案过的域名,直接解析过来即可;如果你要新注册域名,首先自行在网上购买,然后注意域名如果想在国内正常绑定阿里云或腾讯云,需要域名备案。这里的备案流程和传统云主机略有不同,涉及一个uniCloud没有固定ip的问题。此时可以去买花生壳的备案服务;也可以临时买一个短期传统云,走传统备案;还有授权码方案,这里有开发者分享的经验贴:[https://ask.dcloud.net.cn/article/38116](https://ask.dcloud.net.cn/article/38116)
**关于证书内容与私钥**
......@@ -247,6 +249,7 @@ uni-app项目根据路由模式不同需要做不同的配置
- 资源统计页面展示的数据可能会有延迟
- 读次数、写次数、回源流量为系统限制,在现有套餐的容量、流量限制下一般不会超出
- 腾讯云前端网页部署套餐到期之后会保留7天,超过7天将会销毁
- 如果服务空间是包月套餐,在服务空间到期但是前端网页托管未到期的情况下,前端网页托管也会随服务空间销毁,请注意给服务空间续费
## 阿里云使用限制
......
......@@ -10,12 +10,11 @@
**注意**
// 本文件用于,使用JQL语法操作项目关联的uniCloud空间的数据库,方便开发调试和远程数据库管理
// 编写clientDB的js API(也支持常规js语法,比如var),可以对云数据库进行增删改查操作。不支持uniCloud-db组件写法
// 可以全部运行,也可以选中部分代码运行。点击工具栏上的运行按钮或者按下【F5】键运行代码
// 如果文档中存在多条JQL语句,只有最后一条语句生效
// 如果混写了普通js,最后一条语句需是数据库操作语句
// 此处代码运行不受DB Schema的权限控制,移植代码到实际业务中注意在schema中配好permission
// 不支持clientDB的action
// 数据库查询有最大返回条数限制,详见:https://uniapp.dcloud.net.cn/uniCloud/cf-database?id=limit
// 详细JQL语法,请参考 https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=jsquery
\ No newline at end of file
- 编写clientDB的js API(也支持常规js语法,比如var),可以对云数据库进行增删改查操作。不支持uniCloud-db组件写法
- 可以全部运行,也可以选中部分代码运行。点击工具栏上的运行按钮或者按下【F5】键运行代码
- 如果文档中存在多条JQL语句,只有最后一条语句生效
- 如果混写了普通js,最后一条语句需是数据库操作语句
- 此处代码运行不受DB Schema的权限控制,移植代码到实际业务中注意在schema中配好permission
- 不支持clientDB的action
- 数据库查询有最大返回条数限制,详见:[limit](https://uniapp.dcloud.net.cn/uniCloud/cf-database?id=limit)
- 详细JQL语法,请参考:[JQL](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=jsquery)
\ No newline at end of file
......@@ -3,7 +3,7 @@
只需熟悉js即可,然后阅读uniCloud的文档,就像学习一个js框架。
#### dcloud出品的视频教程:
#### DCloud出品的视频教程:
<video style="width:50vw;height:37.5vw;margin-bottom:20px;" id="video" preload="none" controls="controls" poster="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/e5da48fa-33c1-4379-8927-65edc6d05d5f.mp4?x-oss-process=video/snapshot,t_1000,f_jpg" src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/e5da48fa-33c1-4379-8927-65edc6d05d5f.mp4"></video>
- [更多视频教程](https://ke.qq.com/course/3416784?taid=11123338234831568&tuin=4025c735)
......
......@@ -22,7 +22,7 @@ uniCloud提供包月、按量计费两种计费方式(仅腾讯云),具体
|资源类目 |限制 |说明 |
|:-: |:-: |:-: |
|云函数并发限制 |1000个/服务空间 |实际普通项目很难达到这个并发数 |
|云函数并发限制 |1000个实例/服务空间 |实际普通项目很难达到这个并发数,阿里云可以设置单实例多并发单实例最多100,理论最大并发量1000*100=100000 |
|每个服务空间的云函数数量 |48个 |实际项目中由于clientDB和单路由云函数,只会用到几个云函数,达不到限制数字。[详见](https://uniapp.dcloud.net.cn/uniCloud/faq?id=merge-functions) |
尤其注意阿里云的cdn确实是全免费的,这些免费资源可用于正常公司业务,阿里云不允许开发者使用这些免费的存储及CDN资源来开展图床类业务。
......
#### 2021-04-30
+ 【重要】clientDB联表查询策略调整,请参考此文档进行进行排查并调整:[clientDB联表查询策略调整](https://ask.dcloud.net.cn/article/38966)
+ clientDB 新增 联表查询支持副表foreignKey联查,即副表字段的foreignKey指向主表,把副表数据挂在主表下面 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=st-foreign-key)
+ uniCloud本地调试插件 修复 阿里云偶发启动时多请求并发报错的Bug
#### 2021-04-16
+ 【重要】clientDB联表查询策略调整,请参考此文档进行进行排查并调整:[clientDB联表查询策略调整](https://ask.dcloud.net.cn/article/38966)
+ unicloud-db组件 新增 loadtime 属性,替代 manual 属性 [详情](https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=props)
+ unicloud-db组件 新增 foreignKey 属性,用于存在多个foreignKey关系时指定要使用的foreignKey [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=lookup-foreign-key)
+ uniCloud.mixinDataCom 新增 foreignKey 属性,用途同上 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=lookup-foreign-key)
+ uni-id 修复 3.0.7 版本引出的多个用户访问时可能出现30201报错的Bug
+ uni-id 新增 bindMobile 接口支持通过一键登录的方式绑定 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=bind-mobile)
+ uni-id 调整 bindTokenToDevice 选项默认值改为 false,即默认不再与设备绑定,方便多设备登录
+ 修复 uniCloud.chooseAndUploadFile 在iOS微信小程序真机无法唤起选择文件的Bug
+ uniCloud admin 优化错误提示、键盘响应等众多细节,更新uni-id等众多依赖 [详情](https://ext.dcloud.net.cn/plugin?id=3268)
#### 2021-04-07
+ 新增 [uni-upgrade-center](https://uniapp.dcloud.io/uniCloud/upgrade-center),提供了简单、易用、统一的App管理、App版本管理、安装包发布管理,升级检测更新管理。
+ uniCloud本地调试插件 修复 3.1.5 版本引出的腾讯云连接本地云函数运行一段时间后报错的Bug [详情](https://ask.dcloud.net.cn/question/119089)
+ 阿里云 新增 支持对云函数设置单实例并发度 [详情](https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=concurrency)
+ 阿里云 新增 支持TTL索引 [详情](https://uniapp.dcloud.net.cn/uniCloud/db-index?ttl)
#### 2021-03-16
+ unicloud-db组件 add、update、remove方法新增可选参数needConfirm、needLoading、loadingTitle [详情](https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=add)
+ unicloud-db组件 新增 load 事件支持 pagination [详情](https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=loadevent)
......
......@@ -4,7 +4,7 @@
它有很多重要的作用:
- 描述现有的数据格式。可以一目了然的阅读每个表、每个字段的用途。
- 描述现有的数据含义。可以一目了然的阅读每个表、每个字段的用途。
- 设定数据操作权限(permission)。什么样的角色可以读/写哪些数据,都在这里配置。
- 设定字段值域能接受的格式(validator),比如不能为空、需符合指定的正则格式。
- 设定字段之间的约束关系(fieldRules),比如字段结束时间需要晚于字段开始时间。
......@@ -97,6 +97,8 @@ properties里的字段列表,每个字段都有很多可以设置的属性,
|enum|Array|字段值枚举范围,数组中至少要有一个元素,且数组内的每一个元素都是唯一的。|
|enumType|String|字段值枚举类型,可选值tree。设为tree时,代表enum里的数据为树形结构。此时schema2code可生成多级级联选择组件|
|arrayType|String|数组项类型,bsonType="array" 时有效,HBuilderX 3.1.0+ 支持,具体见下表arrayType可用类型|
|fileMediaType|String|文件类型,可选值 all&#124;image&#124;video 默认值为all,表示所有文件,image表示图片类型文件,video表示视频类型文件,详情参考[文件上传示例](https://uniapp.dcloud.net.cn/uniCloud/schema?id=filepicker) HBuilderX 3.1.0+ 支持|
|fileExtName|String|文件扩展名过滤,多个用 "," 分割,例如: jpg,png,HBuilderX 3.1.0+ 支持|
|maximum|number|如果bsonType为数字时,可接受的最大值|
|exclusiveMaximum|boolean|是否排除 maximum|
|minimum|number|如果bsonType为数字时,可接受的最小值|
......@@ -116,15 +118,14 @@ properties里的字段列表,每个字段都有很多可以设置的属性,
|label|string|字段标题。schema2code生成前端代码时,渲染表单项前面的label标题|
|group|string|分组id。schema2code生成前端代码时,多个字段对应的表单项可以合并显示在一个uni-group组件中|
|order|int|表单项排序序号。schema2code生成前端代码时,默认是以schema中的字段顺序从上到下排布表单项的,但如果指定了order,则按order规定的顺序进行排序。如果表单项被包含在uni-group中,则同组内按order排序|
|component|Object&#124;Array|schema2code生成前端代码时,使用什么组件渲染这个表单项。比如使用input输入框。详见下方示例|
|component|Object&#124;Array|schema2code生成前端代码时,使用什么组件渲染这个表单项。已废弃。请使用下面的componentForEdit和componentForShow|
|componentForEdit|Object&#124;Array|HBuilderX 3.1.0+, 生成前端编辑页面文件时(add.vue、edit.vue),使用什么组件渲染这个表单项。比如使用input输入框。|
|componentForShow|Object&#124;Array|HBuilderX 3.1.0+, 生成前端展示页面时(list.vue、detail.vue),使用什么组件渲染。比如使用uni-dateformat格式化日期。|
**注意:**
1. `DB Schema`的各种功能均只支持`clientDB`。如果使用云函数操作数据库,schema的作用仅仅是描述字段信息。同时强烈推荐使用HBuilderX 2.9.5以上版本使用`clientDB`
2. schema2code,入口在uniCloud web控制台的数据库schema界面,注意该功能需搭配HBuilderX 2.9.5+版本。
1. `DB Schema`的各种功能均只支持`clientDB`。如果使用云函数操作数据库,schema的作用仅仅是描述字段信息。同时强烈推荐使用HBuilderX 3.0以上版本使用`clientDB`
2. schema2code,是根据scheme自动生成数据的增删改查页面的功能。入口1在uniCloud web控制台的数据库schema界面,入口2在HBuilderX中点击schema右键菜单。[详见](https://ext.dcloud.net.cn/plugin?id=4684)
3. 暂不支持子属性校验
4. HBuilderX 3.1.0+ `component` 属性升级为 `componentForEdit`,以支持更灵活的配置不同类型的页面使用的组件,仍然兼容`component`
**一个带有字段的schema基本示例**
......@@ -187,7 +188,7 @@ uniCloud推出了`openDB`开源数据库规范,包括用户表、文章表、
- timestamp (时间戳)
- date (日期)
- file 云存储文件的信息体。不直接存储文件,而是一个json object,包括云存储文件的名称、路径、文件体积等信息。
- password (所有用户都不能通过clientDB读写,即使是admin管理员)
- password (一种特殊的string。这类字段不会通过clientDB传递给前端,所有用户都不能通过clientDB读写,即使是admin管理员)
注意:
- timestamp是一串数字的时间戳,一般通过如下js获取`var timestamp = new Date().getTime();`。它的好处是屏蔽了时区差异。阿里云和腾讯云的云端时区是0,但在HBuilderX本地运行云函数时,如果是中国的电脑,时区则会变成8,导致显示错乱。所以推荐使用时间戳。但时间戳是一串记录毫秒的数字,不合适直接渲染到前端界面上。推荐的做法是在前端渲染时使用[`<uni-dateformat>`组件](https://ext.dcloud.net.cn/plugin?id=3279)
......@@ -1011,9 +1012,11 @@ permission的字段级控制,包括读写两种权限,分别称为:read、
**注意**
- `auth.xxx`均由uni-id提供,依赖于[uni-id公共模块](uniCloud/uni-id.md)
- `doc.xxx`表示将要查询/修改/删除的每条数据,如果将要访问的数据不满足permission规则将会拒绝执行
- `uni-id`的角色和权限,也即auth.role和auth.permission是不一样的概念。注意阅读[uni-id 角色权限](/uniCloud/uni-id?id=rbac)
- 如果想支持使用多个`action`的用法,可以通过`"'actionRequired' in action"`的形式配置权限,限制客户端使用的action内必须包含名为`actionRequired`的action
- doc是有客户端条件里面提取的变量,因此create权限内不可使用doc变量,建议使用forceDefaultValue或自定义校验函数实现插入数据的校验。
- doc是由客户端条件里面提取的变量,可以理解为将要访问的数据,因此create权限内不可使用doc变量,建议使用forceDefaultValue或自定义校验函数实现插入数据的校验。
**权限规则内可以使用的运算符**
......@@ -1041,7 +1044,7 @@ permission的字段级控制,包括读写两种权限,分别称为:read、
"permission": {
"read": "doc.status==true", // 任何用户都可以读status字段的值为true的记录,其他记录不可读
"create": false, // 禁止新增数据记录(admin权限用户不受限)
"update": false, // 禁止更新数据(admin权限用户不受限)
"update": "'updateuser' in auth.permission", // 权限标记为updateuser的用户,和admin管理员,可以更新数据,其他人无权更新数据
"delete": false // 禁止删除数据(admin权限用户不受限)
},
"properties": {
......@@ -1086,6 +1089,14 @@ forceDefaultValue属于数据校验的范畴,在数据插入时生效,但是
例如在news表新增一条记录,权限需求是“未登录用户不能创建新闻”,其实不需要在news表的create权限里写`auth.uid != null`。只需把news表的uid字段的forceDefaultValue设为`"$env": "uid"`,create权限配置为true即可,未登录用户自然无法创建。当然实际使用时你可能需要更复杂的权限,直接使用true作为权限规则时务必注意
**permission和role的使用注意**
在schema中使用uni-id的permission和role,首先需要在uniCloud admin中创建好权限,然后创建角色并给该角色分配权限,最后创建用户并授权角色。
这样用户登录后,uniCloud会自动分析它的permission和role,在schema里编写的关于permission和role的限制也可以一一对应上,进行有效管理。
admin中创建权限、角色和用户授权,另见[文档](/uniCloud/admin?id=mutiladmin)
**变量action的说明**
action是`clientDB`的一个配套功能。它的作用是在前端发起数据操作请求时,附带一个action的name,则会同时执行一个`uni-clientDB-action`的云函数。[详见](/uniCloud/database?id=action)
......@@ -1206,14 +1217,26 @@ DCloud提供了`uni-forms`前端组件,该组件的表单校验规范完全符
#### 快速上手schema2code生成“通讯录”
> 成品演示地址:[http://contacts-demo.dcloud.net.cn/](http://contacts-demo.dcloud.net.cn/)
##### 首先创建“带schema的通讯录”数据表
1. 登录 [uniCloud控制台](https://unicloud.dcloud.net.cn),选中“云数据库”
2. 点击新建数据表
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/1ef863ed-d919-46f3-bd01-6092f2ed1e21.jpg)
3. 使用[OpenDB](https://gitee.com/dcloud/opendb)表模板创建: `opendb-contacts` 通讯录表
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/0e2ee195-05ae-4445-af41-45c41b2da70a.jpg)
4. 选中刚创建好的数据表`opendb-contacts`,点击进入表结构schema界面,点击按钮 “schema2code”
##### schema2code有两种方式
- 方式1:在HBuilderX中操作
1.1 下载刚刚创建的通讯录表的schema
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/c2ea33f4-8619-41a6-bd14-5f9ce044985d.jpg)
1.2 项目根目录的 `uniCloud/database/opendb-contacts.schema.json` 文件上点击右键,或者在已打开的 Schema 编辑器点击右键.如果没有该菜单,请在插件市场安装插件:[https://ext.dcloud.net.cn/plugin?id=4684](https://ext.dcloud.net.cn/plugin?id=4684)
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/82f69a99-c652-4cbc-a96b-1cfbe3d40529.jpg)
1.3 弹出一个对话框 `schema2code`,选择要导出的项目类型(uni-app用户端项目还是admin管理端项目),以及表字段名(去掉不需要在前端展现或编辑的字段)
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/fb49118b-364e-412b-9900-f275803cce37.jpg)
1.4 点击对话框右下角的确定按钮,将执行导入动作,如果导入的文件和工程中的文件有差异将弹出文件对比框,继续操作并确认导入
- 方式2:在uniCloud web控制台操作
2.1 选中刚创建好的数据表`opendb-contacts`,点击进入表结构schema界面,点击按钮 “schema2code”
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/3f93a350-2d13-4b8e-afb6-7dc367437b49.jpg)
5. 点击“导入HBuilderX”或“下载zip”按钮,将生成的代码合并到自己的项目中
2.2 点击“导入HBuilderX”或“下载zip”按钮,将生成的代码合并到自己的项目中
![](https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/ba87a6b0-1519-11eb-81ea-f115fe74321c.png)
上图每个区域的解释如下:
......@@ -1253,7 +1276,7 @@ DCloud提供了`uni-forms`前端组件,该组件的表单校验规范完全符
**全程演示视频**
</br>
<video style="width:50vw;height:28vw;" id="video" preload="none" controls="controls"
poster="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b537e2ca-0f4e-4ff0-a097-48fdeafb9873/bfcc37f1-389f-40e9-a538-bf6d53ab0990.mp4?x-oss-process=video/snapshot,t_1000,f_jpg" src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b537e2ca-0f4e-4ff0-a097-48fdeafb9873/bfcc37f1-389f-40e9-a538-bf6d53ab0990.mp4"></video>
poster="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/a04e1d03-6d9f-43bf-a74b-80e9a5c31d7f.mp4?x-oss-process=video/snapshot,t_1000,f_jpg" src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/a04e1d03-6d9f-43bf-a74b-80e9a5c31d7f.mp4"></video>
......@@ -1269,7 +1292,7 @@ const dbOrderBy = 'register_date desc' // 排序字段,asc(升序)、desc(降
const dbSearchFields = ['username', 'role_name', 'mobile', 'email'] // 模糊搜索字段,支持模糊搜索的字段列表
```
`schema2code`是一个代码辅助生成工具,生成后的代码,经常会有二次开发需求。如果二次开发后又变动schema,建议使用Git等工具管理源码,进行差异比对
`schema2code`是一个代码辅助生成工具。
#### 生成页面控件的默认策略
......@@ -1278,7 +1301,8 @@ const dbSearchFields = ['username', 'role_name', 'mobile', 'email'] // 模糊搜
- 如果配置了字段的component属性,则严格按component的配置执行。
- 如果没有配置component属性,那么默认有如下策略:
* 字段类型为bool时,默认使用switch组件
* 字段类型为Array时,默认使用uni-data-checkbox组件
* 字段类型为Array时,默认使用uni-data-checkbox组件(显示为多选框)
* 字段类型为int且使用enum时,默认使用uni-data-checkbox组件(显示为单选框)
* 字段类型为int时,满足以下2个条件时,使用slider组件
- 必填字段
- 配置 `minimum``maximum`
......@@ -1578,6 +1602,31 @@ const dbSearchFields = ['username', 'role_name', 'mobile', 'email'] // 模糊搜
> HBuilderX 3.1.0+ 支持
单个文件上传示例
```json
{
"schema": {
"bsonType": "object",
"required": [],
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"image": {
"bsonType": "file",
"title": "图片",
"description": "图片",
"fileMediaType": "image", // 可选值 all|image|video 默认值为all,表示所有文件,image表示图片类型文件,video表示视频类型文件
"fileExtName": "jpg,png", // 扩展名过滤,多个用 , 分割
}
}
}
}
```
多个文件上传示例
```json
{
"schema": {
......@@ -1592,14 +1641,13 @@ const dbSearchFields = ['username', 'role_name', 'mobile', 'email'] // 模糊搜
"title": "图片",
"description": "图片",
"arrayType": "file",
"fileMediaType":"image", // 可选值 all|image|video 默认值为all,表示所有文件,image表示图片类型文件,video表示视频类型文件
"fileExtName":"jpg,png", // 扩展名过滤,多个用 , 分割
"maxLength": 3, // 限制最大数量
"fileMediaType": "image", // 可选值 all|image|video 默认值为all,表示所有文件,image表示图片类型文件,video表示视频类型文件
"fileExtName": "jpg,png", // 扩展名过滤,多个用 , 分割
"maxLength": 3 // 限制最大数量
}
}
}
}
```
上传后的file对象
......
......@@ -16,10 +16,11 @@
|参数名 |类型 |必填 |说明 |
|:-: |:-: |:-: |:-: |
|appid |String |是 |DCloud appid,可以在项目manifest.json内看到 |
|smsKey |String |是 |调用短信接口的密钥key,从 dev.dcloud.net.cn/uniSms 后台获取 |
|smsSecret |String |是 |调用短信接口的密钥secret,从 dev.dcloud.net.cn/uniSms 后台获取 |
|phone |String |是 |发送目标手机号,暂仅支持中国大陆手机号,不能填写多个手机号|
|templateId |String |是 |模版Id,短信内容为固定模板,详见下方说明 |
|templateId |String |是 |模版Id,短信内容为固定模板,详见下方说明(应用开发阶段,可以使用 DCloud 提供的测试模板) |
|data |Object |是 |模版里的各个变量字段,json格式 |
......@@ -57,6 +58,15 @@
- 短信类别:
分为3类,即验证码类短信、通知类短信、营销类短信。验证码类短信,其模板审核简单快速,只能单次发送。
**短信测试模板说明**
运营商目前审核比较严格,处于开发阶段的应用可能无法通过运营商的审核。为方便开发者测试短信功能,DCloud 提供了一个测试模板,该模板的templateId为:uni_sms_test,内容为:`【DC】尊敬的用户,您的验证码是:${code}。5分钟内有效,请尽快验证。请勿泄漏您的验证码。`
使用该模板的限制:
1. 每日最多给10个手机号发送不超过100条短信;
2. 使用该模板也会正常收取费用,请保证账户有充足余额。
<!--
目前短信功能包括如下模版,暂不可扩展新模版,模版形式如下。参数data内的字段会填充到模版内容里。
......@@ -125,6 +135,7 @@
exports.main = async (event, context) => {
try {
const res = await uniCloud.sendSms({
appid: '__UNI__xxxxxxx',
smsKey: '****************',
smsSecret: '****************',
phone: '188********',
......
......@@ -4,6 +4,38 @@
源码仓库:[https://gitee.com/dcloud/uni-cloud-router](https://gitee.com/dcloud/uni-cloud-router)
---
- [云函数端](#云函数端)
- [安装](#安装)
- [目录结构](#目录结构)
- [控制器(Controller)](#控制器controller)
- [如何编写 Controller](#如何编写-controller)
- [获取请求参数](#获取请求参数)
- [调用 Service](#调用-service)
- [定制 URL 化返回的状态码](#定制-url-化返回的状态码)
- [服务(Service)](#服务service)
- [使用场景](#使用场景)
- [如何编写 Service](#如何编写-service)
- [使用 Service](#使用-service)
- [中间件(Middleware)](#中间件middleware)
- [开发中间件](#开发中间件)
- [使用中间件](#使用中间件)
- [Context](#context)
- [获取方式](#获取方式)
- [客户端](#客户端)
- [发送请求](#发送请求)
- [返回结果](#返回结果)
## 云函数端
### 安装
```bash
npm install --save uni-cloud-router
```
## 介绍
### 目录结构
......@@ -84,7 +116,7 @@ module.exports = class HelloService extends (
```js
sayHello() {
this.request('hello/sayHello', {}).then(res => {
uni.request('hello/sayHello', {}).then(res => {
this.title = res.data
})
}
......@@ -246,7 +278,7 @@ module.exports = (options) => {
// 返回中间件函数
return async function auth(ctx, next) {
// 校验 token
const auth = uniID.checkToken(ctx.event.uniIdToken);
const auth = await uniID.checkToken(ctx.event.uniIdToken);
if (auth.code) {
// 校验失败,抛出错误信息
throw { code: auth.code, message: auth.message };
......@@ -261,28 +293,120 @@ module.exports = (options) => {
- [uni-id 校验 token 中间件](https://github.com/dcloudio/uni-template-admin/blob/master/cloudfunctions-aliyun/uni-admin/middleware/auth.js)
- [uni-id 校验 permission 中间件](https://github.com/dcloudio/uni-template-admin/blob/master/cloudfunctions-aliyun/uni-admin/middleware/permission.js)
- [云函数 URL 化中间件](https://github.com/fxy060608/uni-cloud-router/blob/master/src/middleware/http.ts)
- [云函数URL化 中间件](https://github.com/fxy060608/uni-cloud-router/blob/master/src/middleware/http.ts)
- [ip拦截中间件](https://ext.dcloud.net.cn/plugin?id=4619)
#### 使用中间件
1. 通过 config.js 配置
```js
const auth = require("./middleware/auth.js"); // 引入 auth 中间件
const auth = require('./middleware/auth.js') // 引入 auth 中间件
module.exports = {
debug: true, // 调试模式时,将返回 stack 错误堆栈
baseDir: __dirname, // 指定应用根目录
middleware: [
[
//数组格式,第一个元素为中间件,第二个元素为中间件生效规则配置
auth({ tokenSecret: "tokenSecret-demo" }), // 注册中间件
auth({ tokenSecret: 'tokenSecret-demo' }), // 注册中间件
{ enable: true, ignore: /\/login$/ }, // 配置当前中间件生效规则,该规则表示以`/login`结尾的路由不会执行 auth 中间件校验 token
],
],
};
}
```
2. 中间件配置项
- enable 控制中间件是否开启。
- match 设置
- match 设置只有符合某些规则的请求才会经过这个中间件。
支持类型:
- 字符串:当参数为字符串类型时,配置的是一个 action 前缀,所有以该字符串作为前缀的 action 都会匹配上。
- 正则:当参数为正则时,直接匹配满足正则验证的 action。
- 函数:当参数为一个函数时,会将请求上下文传递给这个函数,根据函数结果(true/false)来判断是否匹配。
- 数组:可以由字符串,正则,函数组成,任意一个匹配到即可
- ignore 设置符合某些规则的请求不经过这个中间件。
支持类型:同 match
### Context
Context 是一个请求级别的对象,在每一次收到用户请求时,会实例化一个 Context 对象,这个对象封装了这次用户请求的信息,并提供了许多便捷的方法来获取请求参数或者设置响应信息。框架会将所有的 Service 挂载到 Context 实例上
#### 获取方式
最常见的 Context 实例获取方式是在 [Middleware](#中间件middleware), [Controller](#控制器controller) 以及 [Service](#服务service) 中。
```js
// 在 Controller 中通过 this.ctx 获取 Context 实例
module.exports = class UserController extends Controller {
async login() {
const data = this.ctx.data // 从 Context 实例上获取请求参数
}
}
```
```js
// 在 Service 中通过 this.ctx 获取 Context 实例
module.exports = class PostService extends Service {
async create(data) {
const auth = this.ctx.auth // 从 Context 实例上获取 auth(需要启用 uni-id 中间件)
}
}
```
```js
// 在 Middleware 中通过 ctx 参数获取 Context 实例
module.exports = (options) => {
// 返回中间件函数
return async function auth(ctx, next) {
const data = ctx.data // 从 Context 实例上获取请求参数
await next()
}
}
```
## 客户端
### 发送请求
```js
// 使用 uniCloud 访问
uniCloud.callFunction({
name: 'router', // 要调用的云函数名称
data: {
action: 'user/login', // 路由地址,对应 controller 下 user.js 的 login 方法
// 参数列表
data: {
// controller 通过 this.ctx.data 获取
username: 'demo',
password: 'demo',
},
},
})
```
```js
// 使用 URL 化 request 访问
uni.request({
url: 'xxxxx/router/user/login', // 路由地址,对应 controller 下 user.js 的 login 方法
data: {
// controller 通过 this.ctx.data 获取
username: 'demo',
password: 'demo',
},
})
```
### 返回结果
```js
{
"code": "", // 异常 code,如:"INVOKE_FUNCTION_FAILED"
"message": "", // 异常信息
"stack": "" // 当 config.js 中配置 debug 为 true 时,返回发生异常的堆栈信息
// 其他信息
}
```
......@@ -26,11 +26,11 @@
提供一个名为`uni-id`的公共模块,该模块封装了一系列API,包括注册、登录、修改密码、设置头像等。
示例工程中还提供了一个`user-center`的云函数,演示在云函数中如何调用`uni-id`公共模块。
示例工程中还提供了一个`user-center`的云函数,演示在云函数中如何调用`uni-id`公共模块。推荐使用[云端一体登录插件](https://ext.dcloud.net.cn/plugin?id=13)
3.前端调用
前端示例通过callfunction调用云函数`user-center`,在注册和登录时保存token。
前端示例通过callfunction调用云函数`user-center`,在注册和登录时保存token。在这个[云端一体登录插件](https://ext.dcloud.net.cn/plugin?id=13)里,有完整的登录、注册、修改密码等前后端代码示例。[详见](https://ext.dcloud.net.cn/plugin?id=13)
uniCloud框架底层,会自动在callfunction时传递`uni-id`的token(uni-app 2.7.13+版本)。在云函数的event中可直接拿到`uni-id`的token。也就是说开发者无需自己管理token了。
......@@ -71,7 +71,7 @@ DCloud暂无计划开发百度、头条、QQ等小程序的登录,以及微博
2.邮箱验证集成
邮箱验证,DCloud暂无计划开发,有需求的开发者欢迎提供pr。
发送邮件验证邮箱真实性,DCloud暂无计划开发,有需求的开发者欢迎提供pr。
3.活体检测
......@@ -89,8 +89,8 @@ DCloud暂无计划开发百度、头条、QQ等小程序的登录,以及微博
**uni_modules版**
1. HBuilderX 3.1.0+
2. 插件市场导入`uni-id`公用模块uni_modules版本,[插件市场 uni-id](https://ext.dcloud.net.cn/plugin?id=2116)
3. 修改公用模块`uni-id`下的`config.json`内所需参数(请参考下面config.json的说明)
2. 插件市场导入`uni-id`公用模块uni_modules版本,HBuilderX会自动导入依赖的`uni-config-center`[插件市场 uni-id](https://ext.dcloud.net.cn/plugin?id=2116)
3. `uni-config-center`公用模块下创建`uni-id`目录,在创建的uni-id目录下再创建`config.json`文件配置uni-id所需参数(请参考下面config.json的说明),**注意:如果HBuilderX版本低于3.1.8,批量上传云函数及公共模块后需要单独再上传一次uni-id**
4.`cloudfunctions/common`下上传`uni-id`模块
5. 在要使用`uni-id`的云函数右键选择`管理公共模块依赖`添加`uni-id`到云函数
6. 创建`uni-id-users``opendb-verify-codes`集合(opendb-verify-codes是验证码表。可以使用示例项目里面的db_init.json进行初始化、也可以在web控制台新建表时选择这些表模块)
......@@ -111,7 +111,7 @@ DCloud暂无计划开发百度、头条、QQ等小程序的登录,以及微博
注意:
- **config.json是一个标准json文件,不支持注释**
- 如果不希望使用config.json初始化而是想自行传入参数,可以使用`init`方法[uniID.init](/uniCloud/uni-id?id=init)
- 如果不希望使用config.json初始化而是想自行传入参数(一般不推荐这么做),可以使用`init`方法[uniID.init](/uniCloud/uni-id?id=init)
> 在云函数URL化的场景无法获取客户端平台信息,可以在调用uni-id相关接口之前(推荐在云函数入口)通过修改context.PLATFORM手动传入客户端平台信息
......@@ -145,7 +145,7 @@ exports.main = async (event, context) => {
"tokenSecret": "tokenSecret-demo", // 生成token所用的密钥,注意修改为自己的,使用一个较长的字符串即可
"tokenExpiresIn": 7200, // 全平台token过期时间,未指定过期时间的平台会使用此值
"tokenExpiresThreshold": 600, // 新增于uni-id 1.1.7版本,checkToken时如果token有效期小于此值则自动获取新token,请注意将新token返回给前端保存,如果不配置此参数则不开启自动获取新token功能
"bindTokenToDevice": true, // 是否将token和设备绑定,设置为true会进行ua校验,默认为true
"bindTokenToDevice": false, // 是否将token和设备绑定,设置为true会进行ua校验,uni-id 3.0.12前默认为true3.0.12及以后版本默认调整为false
"passwordErrorLimit": 6, // 密码错误最大重试次数
"passwordErrorRetryTime": 3600, // 密码错误重试次数超限之后的冻结时间
"autoSetInviteCode": false, // 是否在用户注册时自动设置邀请码,默认不自动设置
......@@ -372,12 +372,46 @@ function hasPermission(token, permission) {
}
```
注意:**在uniCloud admin中,封装了可视化的用户、权限、角色的管理,新增删除修改均支持。**无需自己维护。[详见](https://uniapp.dcloud.net.cn/uniCloud/admin?id=mutiladmin)
# uni-id的API列表@api
`uni-id`作为一个云函数的公共模块,暴露了各种API,供云函数调用。
## 基础功能
### 创建uni-id实例@create-instance
> uni-id 3.0.7及以上版本
用法:`uniID.createInstance(Object CreateInstanceParams);`
CreateInstanceParams内可以传入云函数context
```js
// 云函数代码
const uniID = require('uni-id')
exports.main = async function(event,context) {
const uniIDIns = uniID.createInstance({ // 创建uni-id实例,其上方法同uniID
context: context,
config: {} // 完整uni-id配置信息,使用config.json进行配置时无需传此参数
})
payload = await uniIDIns.checkToken(event.uniIdToken) // 后续使用uniIDIns调用相关接口
if (payload.code) {
return payload
}
const res = await uniIDIns.updateUser({
uid: payload.uid,
nickname: 'user nickname'
})
return res
}
```
**为什么需要自行创建uni-id实例**
默认情况下uni-id某些接口会自动从全局context内获取客户端的PLATFORM(平台,如:app-plus、h5、mp-weixin)信息。但是在单实例多并发的场景下可能无法正确获取(全局对象会被后面的请求覆盖,可能会导致前面一次请求使用了后面一次请求的PLATFORM信息)。因此推荐在开启云函数单实例多并发后,自行为uni-id传入context。
### 用户注册 @register
用法`uniID.register(Object RegisterParams)`
......@@ -492,6 +526,12 @@ uniCloud.callFunction({
| needPermission| Boolean | 否 |设置为true时会在checkToken时返回用户权限(permission)。`uni-id 3.0.0`起,如果配置`"removePermissionAndRoleFromToken": false`此选项不再生效 |
| queryField | Array| 否 |指定从哪些字段中比对username(传入参数均为username),不填默认与数据库内的username字段对比, 可取值'username'、'email'、'mobile'|
> 如果希望使用queryField来允许用户同时使用多种方式登录,需要注意必须限制用户注册用户名不为邮箱格式且不为手机号格式,uni-id内部并未做出此类限制
**注意**
- 使用邮箱时需要用户对应的记录里`email_confirmed`为1才可以登录,手机号同样需要`mobile_confirmed`为1才可以登录
**响应参数**
| 字段 | 类型 | 必填| 说明 |
......@@ -1005,37 +1045,6 @@ exports.main = async function(event,context) {
}
```
### 创建uni-id实例@create-instance
> uni-id 3.0.7及以上版本
用法:`uniID.createInstance(Object CreateInstanceParams);`
CreateInstanceParams内可以传入云函数context,**主要用于在单实例多并发的场景(目前uniCloud还未支持,后续会提供)**
```js
// 云函数代码
const uniID = require('uni-id')
exports.main = async function(event,context) {
const uniIDIns = uniID.createInstance({ // 创建uni-id实例,其上方法同uniID
context: context
})
payload = await uniIDIns.checkToken(event.uniIdToken) // 后续使用uniIDIns调用相关接口
if (payload.code) {
return payload
}
const res = await uniIDIns.updateUser({
uid: payload.uid,
nickname: 'user nickname'
})
return res
}
```
**为什么需要自行创建uni-id实例**
默认情况下uni-id某些接口会自动从全局context内获取客户端的PLATFORM(平台,如:app-plus、h5、mp-weixin)信息。但是在单实例多并发的场景下可能无法正确获取(全局对象会被后面的请求覆盖,可能会导致前面一次请求使用了后面一次请求的PLATFORM信息)。因此推荐在开启云函数单实例多并发后,自行为uni-id传入context。
## 手机号码
### 发送短信验证码@sendsmscode
......@@ -1229,28 +1238,28 @@ exports.main = async function(event,context) {
**参数说明**
| 字段 | 类型 | 必填| 说明 |
| --- | --- | --- | --- |
| access_token | String| 是 |uni.login登录成功后,返回的`access_token`参数
| openid | String| 是 |uni.login登录成功后,返回的`openid`参数 |
| type | String| 否 |指定操作类型,可选值为`login``register`,不传此参数时表现为手机号已注册则登录,手机号未注册则进行注册|
| password |String | 否 |密码,type为`register`时生效 |
| inviteCode |String | 否 |邀请人的邀请码,type为`register`时生效 |
| myInviteCode|String | 否 |设置当前注册用户自己的邀请码,type为`register`时生效 |
| needPermission| Boolean | 否 |设置为true时会在checkToken时返回用户权限(permission),建议在管理控制台中使用 |
| 字段 | 类型 | 必填| 说明 |
| --- | --- | --- | --- |
| access_token | String | 是 |uni.login登录成功后,返回的`access_token`参数 |
| openid | String | 是 |uni.login登录成功后,返回的`openid`参数 |
| type | String | 否 |指定操作类型,可选值为`login``register`,不传此参数时表现为手机号已注册则登录,手机号未注册则进行注册|
| password |String | 否 |密码,type为`register`时生效 |
| inviteCode |String | 否 |邀请人的邀请码,type为`register`时生效 |
| myInviteCode |String | 否 |设置当前注册用户自己的邀请码,type为`register`时生效 |
| needPermission| Boolean | 否 |设置为true时会在checkToken时返回用户权限(permission),建议在管理控制台中使用 |
**响应参数**
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| code | Number| 错误码,0表示成功 |
| message | String|详细信息 |
| message | String|详细信息 |
| uid | String|用户`uid` |
| type | String|操作类型,`login`为登录、`register`为注册|
| mobile | String|登录者手机号 |
| userInfo | Object|用户全部信息 |
| token | String|登录成功之后返回的`token`信息 |
| tokenExpired| String|`token`过期时间 |
| mobile | String|登录者手机号 |
| userInfo | Object|用户全部信息 |
| token | String|登录成功之后返回的`token`信息 |
| tokenExpired| String|`token`过期时间 |
**示例代码**
......@@ -1270,23 +1279,28 @@ exports.main = async function(event,context) {
}
```
### 绑定手机号
### 绑定手机号@bind-mobile
用法:`uniID.bindMobile(Object BindMobileParams)`
**mobileInfo**参数说明
| 字段 | 类型 | 必填| 说明 |
| --- | --- | --- | --- |
| uid | String| 是 |用户Id,可以通过checkToken返回 |
| mobile| String| 是 |用户手机号 |
| code | String| 否 |验证码,为兼容旧版逻辑此参数不填写时不会进行验证码校验,而是直接绑定手机号 |
| 字段 | 类型 | 必填| 说明 |
| --- | --- | --- | --- |
| uid | String| 是 |用户Id,可以通过checkToken返回 |
| mobile | String| 否 |用户手机号 |
| code | String| 否 |验证码,为兼容旧版逻辑此参数不填写时不会进行验证码校验,而是直接绑定手机号 |
| access_token| String| 否 |uni.login登录成功后,返回的`access_token`参数 |
| openid | String| 否 |uni.login登录成功后,返回的`openid`参数 |
| type | String| 否 |通过何种方式绑定手机号,sms(手机号验证码)、univerify(一键登录),默认sms|
type为sms时mobile、code必传,type为univerify时access_token、openid必传
**响应参数**
| 字段| 类型 | 必填| 说明 |
| --- | --- | --- | --- |
| code| Number| 是 |错误码,0表示成功|
| 字段 | 类型 | 必填| 说明 |
| --- | --- | --- | --- |
| code | Number| 是 |错误码,0表示成功|
| message | String| 是 |详细信息 |
**示例代码**
......@@ -1512,6 +1526,12 @@ exports.main = async function(event,context) {
- 登录成功之后应持久化存储token、token过期时间,键值为:`uni_id_token、uni_id_token_expired`,例:`uni.setStorageSync('uni_id_token', res.result.token)`
- App端获取code不可直接调用`uni.login`,详细用法可以看下面示例
**APP微信登录详细配置流程**
1. 在manifest.json内配置微信登录用appid
2. **打包****使用**自定义基座(注意一定要在manifest.json填写微信appid后再制作自定义基座),[自定义基座使用说明](https://ask.dcloud.net.cn/article/35115)
3. 在uni-id的config.json内app-plus对应的微信登录信息内配置appid和appsecret
**参数说明**
| 字段 | 类型 | 必填| 说明 |
......@@ -2909,7 +2929,22 @@ uniCloud admin可以平滑升级到uni-id 3.0.0。如果要缓存角色权限到
从插件市场导入支持uni_modules的uni-id,会自动安装依赖的uni-config-center到uni_modules内。如果此前并没有使用uni-config-center可以直接将uni-id的config.json移至`uni-config-center/uni-id/config.json`即可(可以参照插件市场的uni-id示例项目)
- uni-id会优先使用uni-config-center内添加的配置
- 如果批量上传后报“请在公用模块uni-id的config.json或init方法中内添加配置项”,请重新上传一次`uni-config-center`
- 如果批量上传后报“请在公用模块uni-id的config.json或init方法中内添加配置项”,请重新上传一次`uni-id`
#### 忽略用户名邮箱大小写@case-sensitive
> uni-id 3.1.0及以上版本
uni-id 3.1.0版本主要有以下两个调整
1. 自此版本起会对所有接口中的用户名、邮箱、密码进行前后去空格。
2. 此版本之前uni-id并未忽略用户名及邮箱的大小写。这样导致了一些问题,比如用户在手机上登录不小心就会使用首字母大写的用户名或邮箱,这样就会登录失败,影响用户体验。很多应用/网站的登录都是忽略大小写的,为此uni-id在3.1.0版本起调整为默认忽略用户名、邮箱的大小写。实现方式为将用户名、邮箱均存储为小写,用户输入用户名邮箱时也转化为小写进行匹配
**注意**
- 此调整兼容旧版本,以登录接口为例,优先匹配用户输入用户名对应的账号,如果不存在则匹配全小写用户名对应的账号(uni-id内部进行处理实际不会增加数据库读写次数)
- 新注册用户会将用户名/邮箱存储为全小写格式,老用户可能还存在包含大写字母的邮箱及用户名
# FAQ
......@@ -2917,7 +2952,7 @@ uniCloud admin可以平滑升级到uni-id 3.0.0。如果要缓存角色权限到
+ 每次登录成功都会新增一个token,并且检查所有token的有效期删除过期token。正常情况下客户端应该判断持久化存储的token是否还在有效期内,如果还有效就直接进入应用,不再执行登录。这样相当于用户的每个设备上都存在一个有效期内的token,云端也是。
- 复制token到其他环境校验不通过
+ uni-id内会校验客户端ua,如果是在本地调试可以在云函数内修改`context.CLIENTUA`为生成token的设备ua,切记上线删除此逻辑。如果不需要设备和token绑定,可以在config内配置`bindTokenToDevice: false`来关闭绑定
+ uni-id内会校验客户端ua,如果是在本地调试可以在云函数内修改`context.CLIENTUA`为生成token的设备ua,切记上线删除此逻辑。如果不需要设备和token绑定,可以在config内配置`bindTokenToDevice: false`来关闭绑定`uni-id 3.0.12`及以上版本bindTokenToDevice默认值调整为了false
- username、email、mobile三个字段
+ 三个字段均可能为空,但是建议限制一下插入数据库三个字段的格式,比如username不应是邮箱格式或手机号格式,因为登录时可以选择使用username或mobile或email+密码的方式
......
......@@ -47,6 +47,7 @@ HBuilderX中敲下`udb`代码块,得到如下代码,然后通过collection
|field|string|指定要查询的字段,多个字段用 `,` 分割。不写本属性,即表示查询所有字段。支持用 oldname as newname方式对返回字段重命名|
|where|string|查询条件,对记录进行过滤。[见下](/uniCloud/unicloud-db?id=where)|
|orderby|string|排序字段及正序倒叙设置|
|foreign-key|String|手动指定使用的关联关系,HBuilderX 3.1.10+ [详情](/uniCloud/clientdb?id=lookup-foreign-key)|
|page-data|String|分页策略选择。值为 `add` 代表下一页的数据追加到之前的数据中,常用于滚动到底加载下一页;值为 `replace` 时则替换当前data数据,常用于PC式交互,列表底部有页码分页按钮,默认值为`add`|
|page-current|Number|当前页|
|page-size|Number|每页数据数量|
......@@ -54,18 +55,19 @@ HBuilderX中敲下`udb`代码块,得到如下代码,然后通过collection
|getone|Boolean|指定查询结果是否仅返回数组第一条数据,默认 false。在false情况下返回的是数组,即便只有一条结果,也需要[0]的方式获取。在值为 true 时,直接返回结果数据,少一层数组,一般用于非列表页,比如详情页|
|action|string|云端执行数据库查询的前或后,触发某个action函数操作,进行预处理或后处理,[详情](/uniCloud/uni-clientDB?id=%e4%ba%91%e7%ab%af%e9%83%a8%e5%88%86)。场景:前端无权操作的数据,比如阅读数+1|
|manual|Boolean|是否手动加载数据,默认为 false,页面onready时自动联网加载数据。如果设为 true,则需要自行指定时机通过方法`this.$refs.udb.loadData()`来触发联网,其中的`udb`指组件的ref值。一般onLoad因时机太早取不到this.$refs.udb,在onReady里可以取到|
|gettree|Boolean|是否查询树状结构数据,HBuilderX3.0.5+ [详情](/uniCloud/clientdb?id=gettree)|
|startwith|String|gettree的第一层级条件,此初始条件可以省略,不传startWith时默认从最顶级开始查询,HBuilderX3.0.5+|
|limitlevel|Number|gettree查询返回的树的最大层级。超过设定层级的节点不会返回。默认10级,最大15,最小1,HBuilderX3.0.5+|
|groupby|String|对数据进行分组,HBuilderX3.1.0+|
|gettree|Boolean|是否查询树状结构数据,HBuilderX 3.0.5+ [详情](/uniCloud/clientdb?id=gettree)|
|startwith|String|gettree的第一层级条件,此初始条件可以省略,不传startWith时默认从最顶级开始查询,HBuilderX 3.0.5+|
|limitlevel|Number|gettree查询返回的树的最大层级。超过设定层级的节点不会返回。默认10级,最大15,最小1,HBuilderX 3.0.5+|
|groupby|String|对数据进行分组,HBuilderX 3.1.0+|
|group-field|String|对数据进行分组统计|
|distinct|Boolean|是否对数据查询结果中重复的记录进行去重,默认值false,HBuilderX3.1.0+|
|distinct|Boolean|是否对数据查询结果中重复的记录进行去重,默认值false,HBuilderX 3.1.0+|
|loadtime|String|加载数据时机,默认auto,可选值 auto&#124;onready&#124;manual,[详情](/uniCloud/unicloud-db?id=loadtime) HBuilderX3.1.10+|
|@load|EventHandle|成功回调。联网返回结果后,若希望先修改下数据再渲染界面,则在本方法里对data进行修改|
|@error|EventHandle|失败回调|
TODO:暂不支持in子查询功能。后续会补充
注意:`page-current/page-size` 改变不重置数据(`page-data="replace"`)除外,`collection/action/field/getcount/orderby/where` 改变后清空已有数据
注意:`page-current/page-size` 改变不重置数据(`page-data="replace"`) 和 (`loadtime="manual"`) 除外,`collection/action/field/getcount/orderby/where` 改变后清空已有数据
**示例**
......@@ -202,6 +204,15 @@ where中指定要查询的条件。比如只查询某个字段的值符合一定
```
## loadtime@loadtime
|值|类型|描述|
|:-|:-|:-|
|auto|String|页面就绪后或属性变化后加载数据,默认为auto|
|onready|String|页面就绪后不自动加载数据,属性变化后加载。适合在onready中接收上个页面的参数作为where条件时。|
|manual|String|手动模式,不自动加载数据。如果涉及到分页,需要先手动修改当前页,在调用加载数据|
## 事件@loadevent
......@@ -596,7 +607,7 @@ H5平台,开发模式下浏览器控制台输入 `unidev.clientDB.data`,可
// field 属性 查询book表返回book表内的title、book表内的author、order表内的quantity
<template>
<view>
<unicloud-db v-slot:default="{data, loading, error, options}" collection="order,book" where="'book.title == "三国演义"'" field="book{title,author},quantity">
<unicloud-db v-slot:default="{data, loading, error, options}" collection="order,book" where="'book_id.title == "三国演义"'" field="book_id{title,author},quantity">
<view>
<view v-for="(item, index) in data" :key="index" class="list-item">
{{ item.name}}
......
......@@ -619,6 +619,7 @@ exports.main = async function (event) {
// 注意如果处理成功需要严格按照下面的格式进行返回,否则厂商会持续通知
// 微信处理成功之后
return {
"mpserverlessComposedResponse": true,
statusCode: 200,
headers: {
'content-type': 'text/xml;charset=utf-8'
......@@ -627,6 +628,7 @@ exports.main = async function (event) {
}
// 支付宝处理成功后
return {
"mpserverlessComposedResponse": true,
statusCode: 200,
headers: {
'content-type': 'text/plain'
......
......@@ -73,7 +73,7 @@ uniCloud.callFunction({
// 云函数
exports.main = async function (event){
const res = await uniCloud.getPhoneNumber({
appid: '_UNI_ABCDEFG', // 替换成自己开通一键登录的应用的DCloud appid,使用callFunction方式调用时可以不传(会自动取当前客户端的appid),如果使用云函数URL化的方式访问必须传此参数
appid: '_UNI_ABCDEFG', // 替换成自己开通一键登录的应用的DCloud appid
provider: 'univerify',
apiKey: 'xxx', // 在开发者中心开通服务并获取apiKey
apiSecret: 'xxx', // 在开发者中心开通服务并获取apiSecret
......@@ -124,7 +124,7 @@ exports.main = async function(event){
} = JSON.parse(body)
const res = await uniCloud.getPhoneNumber({
provider: 'univerify',
appid: 'xxx', // DCloud appid,不同于callFunction方式调用,使用云函数Url化需要传递DCloud appid参数
appid: 'xxx', // DCloud appid
apiKey: 'xxx', // 在开发者中心开通服务并获取apiKey
apiSecret: 'xxx', // 在开发者中心开通服务并获取apiSecret
access_token: access_token,
......@@ -194,7 +194,7 @@ exports.main = async function (event){
} = params
const res = await uniCloud.getPhoneNumber({
provider: 'univerify',
appid: 'xxx', // DCloud appid,不同于callFunction方式调用,使用云函数Url化需要传递DCloud appid参数
appid: 'xxx', // DCloud appid
apiKey: 'xxx', // 在开发者中心开通服务并获取apiKey
apiSecret: 'xxx', // 在开发者中心开通服务并获取apiSecret
access_token: access_token,
......
# 升级中心 uni-upgrade-center
# 升级中心 uni-upgrade-center
### 概述
统一管理App及App`Android``iOS`平台上`App安装包``wgt资源包`的发布升级
统一管理 App 及 App `Android``iOS`平台上`App安装包``wgt资源包`的发布升级
基于uniCloud的App升级中心,本插件具有如下特征:
- 云端基于uniCloud云函数实现
基于 uniCloud 的 App 升级中心,本插件具有如下特征:
- 数据库遵循opendb规范
- 云端基于 uniCloud 云函数实现
- 遵循uniCloud Admin框架规范,可直接导入Admin项目中
- 支持App整包升级及wgt资源包升级
- 数据库遵循 opendb 规范
- 遵循 uniCloud Admin 框架规范,可直接导入 Admin 项目中
- 支持 App 整包升级及 wgt 资源包升级
### 为什么需要升级中心?
我们一直致力于为用户提供通用功能统一解决方案,比如unipay、uni-id等。
为了解决开发者维护多个App升级繁琐,重复逻辑过多,管理不便的问题,升级中心应运而生。
提供了简单、易用、统一的App管理、App版本管理、安装包发布管理,升级检测更新管理。
我们一直致力于为用户提供通用功能统一解决方案,比如 unipay、uni-id 等。
为了解决开发者维护多个 App 升级繁琐,重复逻辑过多,管理不便的问题,升级中心应运而生。
提供了简单、易用、统一的 App 管理、App 版本管理、安装包发布管理,升级检测更新管理。
### 使用
升级中心分为两个部分:`uni-upgrade-center Admin管理后台``uni-upgrade-center-app前台检测更新`
#### uni-upgrade-center Admin管理后台
#### uni-upgrade-center Admin 管理后台
负责发布新版和管理历史版本的上下线。
<div align="left">
<img src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-8ed92fab-502d-4290-af3c-1d65c4dbfc4d/42742d4d-ccbb-4c3e-bd37-d12d0439817c.png" alt="发布完成页面" width="800"></img>
</div>
提供了如下功能:
- 应用管理,对App的信息记录和应用版本管理
- 版本管理,可以发布新版,也可方便直观的对当前App历史版本以及线上发行版本进行查看、编辑和删除操作
- 云储存安装包免费CDN加速,使安装包下载的更快、更稳定
- 应用管理,对 App 的信息记录和应用版本管理
- 版本发布信息管理,包括 更新标题,更新内容,版本号,静默更新,强制更新,灵活上线发行 的设置和修改
- 版本管理,可以发布新版,也可方便直观的对当前 App 历史版本以及线上发行版本进行查看、编辑和删除操作
- 原生App安装包,发布Apk更新,用于App的整包更新,可设置是否强制更新
- 版本发布信息管理,包括 更新标题,更新内容,版本号,静默更新,强制更新,灵活上线发行 的设置和修改
- wgt资源包,发布wgt更新,用于App的热更新,可设置是否强制更新,静默更新
- 原生 App 安装包,发布 Apk 更新,用于 App 的整包更新,可设置是否强制更新
- App管理列表及App版本记录列表搜索
- wgt 资源包,发布 wgt 更新,用于 App 的热更新,可设置是否强制更新,静默更新
在插件市场安装,根据readme部署即可。[插件地址](https://ext.dcloud.net.cn/plugin?id=4470)
- App 管理列表及 App 版本记录列表搜索
在插件市场安装,根据 readme 部署即可。[插件地址](https://ext.dcloud.net.cn/plugin?id=4470)
#### uni-upgrade-center-app 前台检测更新
负责前台检查升级更新。
<div align="left" style="display:flex;align-items:center;">
<img src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-8ed92fab-502d-4290-af3c-1d65c4dbfc4d/db1cedf7-e08f-4fbb-954f-dd3b2f0ad81d.jpg" alt="官方升级弹框样式" width="250"></img>
<img style="margin-left:20px;" src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-8ed92fab-502d-4290-af3c-1d65c4dbfc4d/f5c8e20d-847a-4c9e-b001-8600123aeb9f.jpg" alt="使用uni.showModal自定义弹框" width="250"></img>
</div>
提供了如下功能:
- 基于`uni-upgrade-center`一键式检查更新,统一整包与wgt资源包更新
- 基于`uni-upgrade-center`一键式检查更新,统一整包与 wgt 资源包更新
- 自行根据传参完成校验,判断此次更新使用哪种方式
- 一键式升级。弹框、下载、安装、是否强制重启等逻辑已集成
- 下载完成如果取消升级自动缓存安装包,下次进入判断是否符合安装条件,判断不通过则自动清除
- 自行根据传参完成校验,判断此次更新使用哪种方式
- 美观,实用,可自定义扩展
在插件市场安装,根据readme部署即可。[插件地址](https://ext.dcloud.net.cn/plugin?id=4542)
\ No newline at end of file
在插件市场安装,根据 readme 部署即可。[插件地址](https://ext.dcloud.net.cn/plugin?id=4542)
......@@ -162,15 +162,21 @@ package.json在每个`uni_modules`插件中都必须存在,包含了插件的
### 开发 uni_modules 插件
#### 新建uni_modules目录
在uni-app项目根目录下,创建uni_modules目录,在HBuilderX中可以项目右键菜单中点击`新建uni_modules目录`
![](https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/de27eb20-6217-11eb-8a36-ebb87efcf8c0.png)
**Tips**
**Tips:**
- 如果是vue-cli项目,uni_modules目录,位于`src`下,即`src/uni_modules`
#### 新建uni_modules插件
1. 在HBuilderX中uni_modules目录右键点击`新建uni_modules插件`
![](https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/dd758b10-6217-11eb-8a36-ebb87efcf8c0.png)
2. 填写正确的插件ID,选择插件分类
![](https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/dcc6d480-6217-11eb-8a36-ebb87efcf8c0.png)
插件ID命名规范:
- 格式为:'作者ID-插件英文名称',示例:'xx-yy',其中作者ID和插件英文名称只能包含英文、数字
- 作者ID由插件作者自定义,不能使用'DCloud'、'uni'等关键字,长度要求至少2位字符
......
......@@ -165,57 +165,58 @@ uni.login({
univerifyStyle 数据结构:
```json
{
"fullScreen": true, // 是否全屏显示,true表示全屏模式,false表示非全屏模式,默认值为false
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"backgroundImage": "bg.png", // 背景图片,仅在全屏模式下生效
"icon": {
"path": "static/xxx.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
},
"phoneNum": {
"color": "#000000", // 手机号文字颜色 默认值:#000000
},
"slogan": {
"color": "#8a8b90", // slogan 字体颜色 默认值:#8a8b90
},
"authButton": {
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
"highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
"disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)
"textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff
"title": "本机号码一键登录" // 授权按钮文案 默认值:“本机号码一键登录”
},
"otherLoginButton": {
"visible": "true", // 是否显示其他登录按钮,默认值:true
"normalColor": "#f8f8f8", // 其他登录按钮正常状态背景颜色 默认值:#f8f8f8
"highlightColor": "#dedede", // 其他登录按钮按下状态背景颜色 默认值:#dedede
"textColor": "#000000", // 其他登录按钮文字颜色 默认值:#000000
"title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”
"borderWidth": "1px", // 边框宽度 默认值:1px(仅ios支持)
"borderColor": "#c5c5c5" //边框颜色 默认值: #c5c5c5(仅ios支持)
},
"privacyTerms": {
"defaultCheckBoxState":"true", // 条款勾选框初始状态 默认值: true
"textColor": "#8a8b90", // 文字颜色 默认值:#8a8b90
"termsColor": "#1d4788", // 协议文字颜色 默认值: #1d4788
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录
"fontSize":12, // 隐私协议文字大小 (仅android 支持)
"privacyItems": [
// 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
{
"url": "https://", // 点击跳转的协议详情页面
"title": "用户服务协议" // 协议名称
}
]
}
{
"fullScreen": "false", // 是否全屏显示,默认值: "false"
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)
"icon": {
"path": "static/xxx.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
},
"phoneNum": {
"color": "#202020" // 手机号文字颜色 默认值:#202020
},
"slogan": {
"color": "#BBBBBB" // slogan 字体颜色 默认值:#BBBBBB
},
"authButton": {
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
"highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
"disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)
"textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff
"title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”
"borderRadius": "24px" // 授权按钮圆角 默认值:"24px" (按钮高度的一半)
},
"otherLoginButton": {
"visible": "true", // 是否显示其他登录按钮,默认值:true
"normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明
"highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明
"textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565
"title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”
"borderColor": "", //边框颜色 默认值:透明(仅iOS支持)
"borderRadius": "0px" // 其他登录按钮圆角 默认值:"0px"
},
"privacyTerms": {
"defaultCheckBoxState":"true", // 条款勾选框初始状态 默认值: true
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"privacyItems": [
// 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
{
"url": "https://", // 点击跳转的协议详情页面
"title": "用户服务协议" // 协议名称
}
]
}
}
```
univerifyStyle 属性对应配置的界面指示图
![](https://dcloud-img.oss-cn-hangzhou.aliyuncs.com/client/doc/univerify/styles.png)
全屏效果 | 非全屏效果
:--------:|:--------:
<img src="https://img.cdn.aliyun.dcloud.net.cn/client/doc/univerify/full_styles_v2.png" width=240> | <img src="https://img.cdn.aliyun.dcloud.net.cn/client/doc/univerify/half_styles_v2.png" width=240>
返回数据示例
......@@ -465,12 +466,16 @@ exports.main = async(event) => {
### 错误码
| 错误码 | 错误描述 |
| -:- | -:- |
| -7 | uniAppid 缺失,检查是否配置/已通过审核 |
| 1000 | 当前 uniAppid 尚未开通一键登录 |
| 1001 | 应用所有者账号信息异常,请检查账号一键登录服务是否正常 |
| 1002 | 应用所有者账号信息异常,请检查账号余额是否充足 |
| 4001 | 请求参数异常 |
| 4003 | 开发者账户appid 校验异常,联系官方人员 |
| 5000 | 服务器未知异常,联系官方人员 |
| 30001 | 当前网络环境不适合执行该操作 |
| 30002 | 用户点击了其他登录方式 |
| 30003 | 用户关闭验证界面 |
......@@ -478,8 +483,12 @@ exports.main = async(event) => {
| 30005 | 预登录失败 |
| 30006 | 一键登录失败 |
| 30007 | 获取本机号码校验token失败 |
| 30008 | 用户点击了自定义按钮 |
| 40004 | 应用不存在 |
| 40047 | 一键登录取号失败 |
| 40053 | 手机号校验失败 |
| 40201 | 源IP鉴权失败 |
## 运行基座和打包
......@@ -499,9 +508,23 @@ exports.main = async(event) => {
预登录有效期为10分钟,超过10分钟后预登录失效,此时调用login授权登录相当于之前没有调用过预登录,大概需要等待1-2秒才能弹出授权界面。
预登录只能使用一次,调用login弹出授权界面后,如果用户操作取消登录授权,再次使用一键登录时需要重新调用预登录。
- **双卡手机能否同时获取两个手机号码**
不支持同时获取两个手机号,
双卡手机以开启数据流量的 SIM 卡进行认证。
- **提示“非移动网关ip地址”**
大多数情况 是因为部分特定设备,不支持双卡双待的网络环境
- **错误代码 40201,提示“源IP鉴权失败”**
检查一下手机卡类型是否是正常运营商手机卡,关闭飞行模式后重新尝试
- **错误代码 40004,提示“应用不存在”**
多出现在自定义基座的场景,请确保应用已通过审核后,且已重新打包。
- **错误代码 30005,提示“预登录失败”**
不具备一键登录的使用前提,设备不支持/未开启数据流量/其他原因
......@@ -25,7 +25,7 @@
|Vue.set | 向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新 [详情](https://cn.vuejs.org/v2/api/#Vue-set)|√ | √|√ | |
|Vue.delete | 删除对象的 property。如果对象是响应式的,确保删除能触发更新视图 [详情](https://cn.vuejs.org/v2/api/#Vue-delete) |√ | √ | √ | |
|Vue.directive | 注册或获取全局指令 [详情](https://cn.vuejs.org/v2/api/#Vue-directive)|√ |√ | x | |
|Vue.filter | 注册或获取全局过滤器 [详情](https://cn.vuejs.org/v2/api/#Vue-filter)|√ |√ | |App端旧版不可以在class中使用 |
|Vue.filter | 注册或获取全局过滤器 [详情](https://cn.vuejs.org/v2/api/#Vue-filter)|√ |√ | x |App端旧版不可以在class中使用 |
|Vue.component | 注册或获取全局组件。注册还会自动使用给定的 id 设置组件的名称 [详情](https://cn.vuejs.org/v2/api/#Vue-component) |√ | √ | √ | |
|Vue.use | 安装 Vue.js 插件 [详情](https://cn.vuejs.org/v2/api/#Vue-use) |√ | √ | √ | |
|Vue.mixin | 全局注册一个混入,影响注册之后所有创建的每个 Vue 实例 [详情](https://cn.vuejs.org/v2/api/#Vue-mixin) |√ |√ | √ | |
......@@ -66,6 +66,25 @@
## 生命周期
|生命周期钩子 |描述 |H5 |App端|微信小程序 |说明 |
| -- | -- | --|-- |-- | -- |
|beforeCreate | 在实例初始化之后被调用 [详情](https://cn.vuejs.org/v2/api/#beforeCreate) |√ |√ | √ | |
|created | 在实例创建完成后被立即调用 [详情](https://cn.vuejs.org/v2/api/#created) |√ | √ | √ | |
|beforeMount | 在挂载开始之前被调用 [详情](https://cn.vuejs.org/v2/api/#beforeMount)|√ | √|√ | |
|mounted | 挂载到实例上去之后调用 [详情](https://cn.vuejs.org/v2/api/#mounted) 注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTick [详情](https://cn.vuejs.org/v2/api/#Vue-nextTick) |√ | √ | √ | |
|beforeUpdate | 数据更新时调用,发生在虚拟 DOM 打补丁之前 [详情](https://cn.vuejs.org/v2/api/#beforeUpdate)|√ |√ | √ | |
|updated | 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子 [详情](https://cn.vuejs.org/v2/api/#updated)|√ |√ | √ | |
|activated | 被 keep-alive 缓存的组件激活时调用 [详情](https://cn.vuejs.org/v2/api/#activated) |√ | √ | x | |
|deactivated | 被 keep-alive 缓存的组件停用时调用 [详情](https://cn.vuejs.org/v2/api/#deactivated) |√ | √ | x | |
|beforeDestroy | 实例销毁之前调用。在这一步,实例仍然完全可用 [详情](https://cn.vuejs.org/v2/api/#beforeDestroy) |√ |√ | √ | |
|destroyed | Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁 [详情](https://cn.vuejs.org/v2/api/#destroyed) |√ | √ | √ | |
|errorCaptured | 当捕获一个来自子孙组件的错误时被调用 [详情](https://cn.vuejs.org/v2/api/#errorCaptured) |√ | √ | √ | - |
## 实例属性
......@@ -160,6 +179,7 @@
|transition-group | 作为多个元素/组件的过渡效果 [详情](https://cn.vuejs.org/v2/api/#transition-group) |√ | x | x | |
|keep-alive | 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们 [详情](https://cn.vuejs.org/v2/api/#keep-alive) |√ |x | x | |
|slot | 作为组件模板之中的内容分发插槽 [详情](https://cn.vuejs.org/v2/api/#slot) |√ | √ | √ | - |
|template | 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性 [详情](https://uniapp.dcloud.io/component/vue-component?id=template) |√ | √ | √ | - |
......
......@@ -261,6 +261,120 @@ vue 是单页面应用,使页面局部刷新,不用每次跳转页面都要
{{msg}}里的内容将会被替代为对应数据对象上msg的值。无论何时,绑定的数据对象上msg发生了改变,插值处的内容都会更新。
#### 使用 JavaScript 表达式
迄今为止,在我们的模板中,我们一直都只绑定简单的 `property` 键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 `JavaScript` 表达式支持。
```html
<template>
<view>
<view>{{ number + 1 }}</view>
<view>{{ ok ? 'YES' : 'NO' }}</view>
<!-- 把一个字符串分割成字符串数组,颠倒其元素的顺序,把数组中的所有元素放入一个字符串 -->
<view>{{ message.split('').reverse().join('') }}</view>
</view>
</template>
<script>
export default {
data() {
return {
number:1,
ok:true,
message: 'Hello Vue!'
}
}
}
</script>
```
```html
<template>
<view>
<view v-for="(item,index) in 10">
<!-- 通过%运算符求余数,实现隔行换色的效果 -->
<view :class="'list-' + index%2">{{index%2}}</view>
</view>
</view>
</template>
<script>
export default {
data() {
return { }
}
}
</script>
<style>
.list-0{
background-color: #aaaaff;
}
.list-1{
background-color: #ffaa7f;
}
</style>
```
这些表达式会在所属 Vue 实例的数据作用域下作为 `JavaScript` 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
```html
<template>
<view>
<!-- 这是语句,不是表达式 -->
<view>{{ var a = 1 }}</view>
<!-- 流控制也不会生效,请使用三元表达式 -->
<view>{{ if (ok) { return message } }}</view>
</view>
</template>
<script>
export default {
data() {
return {
ok:true,
message: 'Hello Vue!'
}
}
}
</script>
```
> 模板表达式都被放在沙盒中,只能访问**全局变量的一个白名单**:
> - `Infinity`
> - `undefined`
> - `NaN`
> - `isFinite`
> - `isNaN`
> - `parseFloat`
> - `parseInt`
> - `decodeURI`
> - `decodeURIComponent`
> - `encodeURI`
> - `encodeURIComponent`
> - `Math`
> - `Number`
> - `Date`
> - `Array`
> - `Object`
> - `Boolean`
> - `String`
> - `RegExp`
> - `Map`
> - `Set`
> - `JSON`
> - `Intl`
>
> 你不应该在模板表达式中试图访问用户定义的全局变量。
### 指令
......@@ -299,7 +413,7 @@ vue 是单页面应用,使页面局部刷新,不用每次跳转页面都要
#### v-on
v-on 指令,它用于监听 DOM 事件。v-on缩写为‘ @ ’
v-on 指令,它用于监听 DOM 事件。v-on缩写为‘ @ ’,下文简称为 @事件
```html
......@@ -856,12 +970,12 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
### 监听事件
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 `JavaScript` 代码。
可以用@事件监听 DOM 事件,并在触发时运行一些 `JavaScript` 代码。
```html
<template>
<view>
<button v-on:click="counter += 1">Add 1</button>
<button @click="counter += 1">Add 1</button>
<text>The button above has been clicked {{ counter }} times.</text>
</view>
</template>
......@@ -879,7 +993,7 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
### 事件处理方法
然而许多事件处理逻辑会更为复杂,所以直接把 `JavaScript` 代码写在 `v-on` 指令中是不可行的。因此 `v-on` 还可以接收一个需要调用的方法名称。
然而许多事件处理逻辑会更为复杂,所以直接把 `JavaScript` 代码写在@事件中是不可行的。因此@事件还可以接收一个需要调用的方法名称。
示例:
......@@ -887,7 +1001,7 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
<template>
<view>
<!-- `greet` 是在下面定义的方法名 -->
<button v-on:click="greet">Greet</button>
<button @click="greet">Greet</button>
</view>
</template>
<script>
......@@ -921,8 +1035,8 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
```html
<template>
<view>
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
<button @click="say('hi')">Say hi</button>
<button @click="say('what')">Say what</button>
</view>
</template>
<script>
......@@ -943,7 +1057,7 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
```html
<template>
<view>
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
<button @click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
</view>
......@@ -954,7 +1068,7 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
warn(message, event) {
// 现在我们可以访问原生事件对象
if (event) {
event.preventDefault()
//可访问 event.target等原生事件对象
}
uni.showToast({
title: message
......@@ -971,12 +1085,12 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
### 事件修饰符
修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,`.prevent` 修饰符告诉 `v-on` 指令对于触发的事件调用 `event.preventDefault()`
修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,`.prevent` 修饰符告诉 @事件对于触发的事件调用 `event.preventDefault()`
v-on 提供了事件修饰符:
@事件(v-on)提供了事件修饰符:
- `.stop`: 各平台均支持, 使用时会阻止事件冒泡,在非 H5 端同时也会阻止事件的默认行为
- `.native`: 监听原生事件,仅在 H5 平台支持
- `.native`: 监听原生事件,各平台均支持
- `.prevent`: 仅在 H5 平台支持
- `.capture`: 仅在 H5 平台支持
- `.self`: 仅在 H5 平台支持
......@@ -986,15 +1100,16 @@ v-on 提供了事件修饰符:
```html
<!-- 阻止单击事件继续传播 -->
<view v-on:click.stop="doThis"></view>
<view @click.stop="doThis"></view>
```
> 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 `v-on:click.prevent.self` 会阻止所有的点击,而 `v-on:click.self.prevent` 只会阻止对元素自身的点击。
> 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 `@click.prevent.self` 会阻止所有的点击,而 `@click.self.prevent` 只会阻止对元素自身的点击。
**注意**
- 为兼容各端,事件需使用 **v-on****@** 的方式绑定,请勿使用小程序端的 `bind``catch` 进行事件绑定。
- 为兼容各端,事件需使用 **@** 的方式绑定,请勿使用小程序端的 `bind``catch` 进行事件绑定;也不能在 JS 中使用`event.preventDefault()``event.stopPropagation()`方法;
- 若需要禁止蒙版下的页面滚动,可使用 `@touchmove.stop.prevent="moveHandle"``moveHandle` 可以用来处理 `touchmove` 的事件,也可以是一个空函数。
```html
......
......@@ -470,7 +470,9 @@
### 将原生事件绑定到组件
你可能有很多次想要在一个组件的根元素上直接监听一个原生事件。
这时,你可以使用 `v-on``.native` 修饰符:
这时,你可以使用 @事件的 `.native` 修饰符:
- 注意:在app、小程序端和h5端表现不一致,h5端获取到的是浏览器原生事件。
```html
<template>
......@@ -938,7 +940,7 @@ Vue 实现了一套内容分发的 API,将 `slot` 元素作为承载分发内
## 小程序不支持列表
- 作用域插槽(字节小程序不支持、除支付宝小程序外仅支持解构插槽、不可使用作用域外数据)
- 作用域插槽(仅支持解构插槽、插槽内不支持复杂表达式且不可使用作用域外数据)
- 动态组件
- 异步组件
- `inline-template`
......
......@@ -197,7 +197,7 @@ Vue.use(Vuex);//vue的插件机制
//Vuex.Store 构造器选项
const store = new Vuex.Store({
state:{//存放状态
"username":"foo"
"username":"foo",
"age":18
}
})
......
......@@ -546,7 +546,9 @@ export default {
exec = exec.action(action)
}
exec.collection(this.collection).where({
const collection = this.collection.indexOf(',') > 0 ? this.collection.substring(0, this.collection.indexOf(',')) : this.collection
exec.collection(collection).where({
_id: dbCmd.in(ids)
}).remove().then((res) => {
success && success(res.result)
......
......@@ -21,14 +21,14 @@ module.exports = (api, options) => {
'--host': `specify host (default: ${defaults.host})`,
'--port': `specify port (default: ${defaults.port})`,
'--https': `use https (default: ${defaults.https})`,
'--public': 'specify the public network URL for the HMR client',
'--auto-host': 'specify automator host',
'--public': 'specify the public network URL for the HMR client',
'--auto-host': 'specify automator host',
'--auto-port': 'specify automator port'
}
}, async function serve (args) {
info('Starting development server...')
info('Starting development server...')
require('./util').initAutomator(args)
require('./util').initAutomator(args)
// although this is primarily a dev server, it is possible that we
// are running it in a mode with a production env, e.g. in E2E tests.
......@@ -199,10 +199,10 @@ module.exports = (api, options) => {
})
}
return new Promise((resolve, reject) => {
const {
runByHBuilderX
} = require('@dcloudio/uni-cli-shared')
return new Promise((resolve, reject) => {
const {
runByHBuilderX
} = require('@dcloudio/uni-cli-shared')
// log instructions & open browser on first compilation complete
let isFirstCompile = true
compiler.hooks.done.tap('vue-cli-service uni-serve', stats => {
......@@ -224,9 +224,9 @@ module.exports = (api, options) => {
printRunningAt && console.log(' App running at:')
printRunningAt && console.log(
` - Local: ${chalk.cyan(urls.localUrlForTerminal)} ${copied}`
)
if (!printRunningAt) {
console.log('Build complete. Watching for changes...')
)
if (!printRunningAt) {
console.log('Build complete. Watching for changes...')
}
if (!isInContainer) {
printRunningAt && console.log(` - Network: ${chalk.cyan(networkUrl)}`)
......@@ -260,11 +260,6 @@ module.exports = (api, options) => {
isFirstCompile = false
if (!isProduction) {
if (process.UNI_CLOUD) {
console.warn(
'当前项目使用了uniCloud,为避免云函数调用跨域问题,建议在HBuilderX内置浏览器里调试,如使用外部浏览器需处理跨域,详见:https://uniapp.dcloud.io/uniCloud/quickstart?id=useinh5'
)
}
// const buildCommand = hasProjectYarn(api.getCwd()) ? `yarn build` : `npm run build`
// console.log(` Note that the development build is not optimized.`)
// console.log(` To create a production build, run ${chalk.cyan(buildCommand)}.`)
......@@ -343,4 +338,4 @@ function checkInContainer () {
module.exports.defaultModes = {
serve: 'development'
}
}
......@@ -96,6 +96,7 @@ module.exports = function chainWebpack (platformOptions, vueOptions, api) {
'process.env.UNI_ENV': JSON.stringify(process.env.UNI_PLATFORM),
'process.env.UNI_CLOUD_PROVIDER': process.env.UNI_CLOUD_PROVIDER,
'process.env.UNICLOUD_DEBUG': process.env.UNICLOUD_DEBUG,
'process.env.RUN_BY_HBUILDERX': process.env.RUN_BY_HBUILDERX,
'process.env.UNI_AUTOMATOR_WS_ENDPOINT': JSON.stringify(process.env.UNI_AUTOMATOR_WS_ENDPOINT)
}
if (process.env.UNI_USING_VUE3) {
......@@ -138,4 +139,4 @@ module.exports = function chainWebpack (platformOptions, vueOptions, api) {
webpackConfig.plugins.delete('progress')
}
}
}
}
......@@ -32,22 +32,38 @@ process.env.VUE_APP_NAME = manifestJsonObj.name
process.env.UNI_USING_V3_SCOPED = true
process.UNI_CLOUD = false
process.UNI_CLOUD_TCB = false
process.UNI_CLOUD_ALIYUN = false
process.env.UNI_CLOUD_PROVIDER = JSON.stringify([])
const isH5 = !process.env.UNI_SUB_PLATFORM && process.env.UNI_PLATFORM === 'h5'
const isProduction = process.env.NODE_ENV === 'production'
if (process.env.UNI_CLOUD_SPACES) {
try {
const spaces = JSON.parse(process.env.UNI_CLOUD_SPACES)
if (Array.isArray(spaces)) {
process.UNI_CLOUD = spaces.length > 0
process.UNI_CLOUD_TCB = !!spaces.find(space => !space.clientSecret)
process.UNI_CLOUD_ALIYUN = !!spaces.find(space => space.clientSecret)
const hasUniCloudSpace = spaces.length > 0
if (spaces.length === 1) {
const space = spaces[0]
console.log(`本项目的uniCloud使用的默认服务空间spaceId为:${space.id}`)
}
if (
hasUniCloudSpace &&
isH5 &&
isProduction
) {
console.warn(
'发布H5,需要在uniCloud后台操作,绑定安全域名,否则会因为跨域问题而无法访问。教程参考:https://uniapp.dcloud.io/uniCloud/quickstart?id=useinh5')
} else if (
hasUniCloudSpace &&
isH5 &&
!isProduction
) {
console.warn(
'当前项目使用了uniCloud,为避免云函数调用跨域问题,建议在HBuilderX内置浏览器里调试,如使用外部浏览器需处理跨域,详见:https://uniapp.dcloud.io/uniCloud/quickstart?id=useinh5'
)
}
process.env.UNI_CLOUD_PROVIDER = JSON.stringify(spaces.map(space => {
if (space.clientSecret) {
return {
......@@ -69,16 +85,6 @@ if (process.env.UNI_CLOUD_SPACES) {
} catch (e) {}
}
if (
process.UNI_CLOUD &&
!process.env.UNI_SUB_PLATFORM &&
process.env.UNI_PLATFORM === 'h5' &&
process.env.NODE_ENV === 'production'
) {
console.warn(
'发布H5,需要在uniCloud后台操作,绑定安全域名,否则会因为跨域问题而无法访问。教程参考:https://uniapp.dcloud.io/uniCloud/quickstart?id=useinh5')
}
// 初始化环境变量
const defaultOutputDir = '../../../../dist/' +
(process.env.NODE_ENV === 'production' ? 'build' : 'dev') + '/' +
......@@ -110,7 +116,9 @@ const {
isSupportSubPackages,
runByHBuilderX,
getPagesJson
} = require('@dcloudio/uni-cli-shared')
} = require('@dcloudio/uni-cli-shared')
process.env.RUN_BY_HBUILDERX = JSON.stringify(runByHBuilderX)
const {
initUniModules
......
......@@ -246,7 +246,7 @@ function processCss(css) {
.replace(VAR_WINDOW_LEFT, '0px')
.replace(VAR_WINDOW_RIGHT, '0px')
}
return css.replace(/\{[\s\S]+?\}|@media.+\{/g, function (css) {
return css.replace(/\{[\s\S]+?\}|@media.+?\{/g, function (css) {
return css.replace(UPX_RE, function (a, b) {
return uni.upx2px(b) + 'px'
})
......
......@@ -253,7 +253,7 @@ function processCss(css) {
.replace(BODY_SCOPED_RE, page)
.replace(BODY_RE, '')
.replace(PAGE_SCOPED_RE, 'body.' + page + ' uni-page-body')
.replace(/\{[\s\S]+?\}|@media.+\{/g, function (css) {
.replace(/\{[\s\S]+?\}|@media.+?\{/g, function (css) {
if(typeof uni === 'undefined'){
return css
}
......
......@@ -45,7 +45,7 @@ export function getTargetDataset (target) {
const $attrs = vm.$attrs
for (const key in $attrs) {
if (key.startsWith('data-')) {
const newKey = camelize(key.substr(5))
const newKey = camelize(key.substr(5).toLowerCase())
const value = $attrs[key]
dataset[newKey] = force ? value : dataset[newKey] || value
}
......
......@@ -253,7 +253,7 @@ export default {
_onTrack: function (e) {
if (!this.disabled) {
return e.detail.state === 'move' ? (this._onUserChangedValue({
x: e.detail.x0
x: e.detail.x
}), this.$trigger('changing', e, {
value: this.sliderValue
}), !1) : (e.detail.state === 'end' && this.$trigger('change', e, {
......
<template>
<uni-textarea v-on="$listeners">
<div class="uni-textarea-wrapper">
<div
ref="wrapper"
class="uni-textarea-wrapper"
>
<div
v-show="!(composing || valueSync.length)"
ref="placeholder"
......@@ -144,7 +147,8 @@ export default {
lineCount
})
if (this.autoHeight) {
this.$el.style.height = this.height + 'px'
this.$el.style.height = 'auto'
this.$refs.wrapper.style.height = this.height + 'px'
}
}
},
......@@ -246,7 +250,6 @@ uni-textarea {
line-height: normal;
white-space: pre-wrap;
word-break: break-all;
box-sizing: content-box !important;
}
uni-textarea[hidden] {
display: none;
......
......@@ -194,20 +194,31 @@ export default {
this._onInput($event, true)
}
this.focusSync = false
const field = $event.target
let cursor
if (field.type === 'number') {
field.type = 'text'
cursor = field.selectionEnd
field.type = 'number'
} else {
cursor = field.selectionEnd
}
this.$trigger('blur', $event, {
value: this.valueSync,
cursor: $event.target.selectionEnd
cursor
})
},
_checkSelection () {
if (this.focusSync && this.selectionStartNumber > -1 && this.selectionEndNumber > -1) {
this._field.selectionStart = this.selectionStartNumber
this._field.selectionEnd = this.selectionEndNumber
const field = this._field
if (this.focusSync && this.selectionStartNumber > -1 && this.selectionEndNumber > -1 && field.type !== 'number') {
field.selectionStart = this.selectionStartNumber
field.selectionEnd = this.selectionEndNumber
}
},
_checkCursor () {
if (this.focusSync && this.selectionStartNumber < 0 && this.selectionEndNumber < 0 && this.cursorNumber > -1) {
this._field.selectionEnd = this._field.selectionStart = this.cursorNumber
const field = this._field
if (this.focusSync && this.selectionStartNumber < 0 && this.selectionEndNumber < 0 && this.cursorNumber > -1 && field.type !== 'number') {
field.selectionEnd = field.selectionStart = this.cursorNumber
}
}
}
......
......@@ -35,8 +35,8 @@ export default {
changedTouches: $event.changedTouches,
detail: {
state,
x0: x,
y0: y,
x: x,
y: y,
dx: x - x0,
dy: y - y0,
ddx: x - x1,
......
......@@ -81,6 +81,7 @@ class InteractiveAd {
this._adError = ''
this._adpid = options.adpid
this._provider = options.provider
this._userData = options.userData
this._isLoaded = false
this._isLoading = false
this._loadPromiseResolve = null
......@@ -99,6 +100,9 @@ class InteractiveAd {
provider: this._provider,
success: (res) => {
this._ad = res
if (this._userData) {
this.bindUserData(this._userData)
}
this._loadAd()
},
fail: (err) => {
......@@ -164,6 +168,12 @@ class InteractiveAd {
}
}
bindUserData (data) {
if (this._ad !== null) {
this._ad.bindUserData(data)
}
}
_loadAd () {
if (this._ad !== null) {
if (this._isLoading === true) {
......
......@@ -31,7 +31,7 @@ export function login (params, callbackId) {
authResult: authResult,
errMsg: 'login:ok'
})
}, errorCallback, provider === 'apple' ? { scope: 'email' } : { univerifyStyle: params.univerifyStyle } || {})
}, errorCallback, provider === 'apple' ? { scope: 'email' } : { univerifyStyle: univerifyButtonsClickHandling(params.univerifyStyle, errorCallback) } || {})
}
// 先注销再登录
// apple登录logout之后无法重新触发获取email,fullname;一键登录无logout
......@@ -128,5 +128,28 @@ export function preLogin (params, callbackId) {
}
export function closeAuthView () {
getService('univerify').then(service => service.closeAuthView())
return getService('univerify').then(service => service.closeAuthView())
}
/**
* 一键登录自定义登陆按钮点击处理
*/
function univerifyButtonsClickHandling (univerifyStyle, errorCallback) {
if (univerifyStyle.buttons &&
Object.prototype.toString.call(univerifyStyle.buttons.list) === '[object Array]' &&
univerifyStyle.buttons.list.length > 0
) {
univerifyStyle.buttons.list.forEach((button, index) => {
univerifyStyle.buttons.list[index].onclick = function () {
closeAuthView().then(() => {
errorCallback({
code: '30008',
message: '用户点击了自定义按钮',
index
})
})
}
})
}
return univerifyStyle
}
......@@ -143,9 +143,6 @@ export default {
}
})
},
beforeDestroy () {
window.removeEventListener('message', this.__messageHandle, false)
},
methods: {
_choose () {
if (this.selected) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册