提交 3b76535a 编写于 作者: Q qiang

Merge branch 'master' into dev

......@@ -65,7 +65,7 @@
<img src="//img-cdn-qiniu.dcloud.net.cn/uniapp/doc/qq@2x.png" width="20" height="20"/>
<div class="contact-smg">
<div>官方QQ交流群</div>
<div>6:697264024 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=SP8-OAARtiYc3heIMYDBNfffG3I5utCy&jump_from=webapi">点此加入</a></div>
<div>20:165796402 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=2jQQukeVdbptonlHsWatgBN8Ef_pRdcj&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -81,7 +81,7 @@
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<div>群21:717019120(2000人已满)</div>
<div>群20:165796402(2000人已满)</div>
<!-- <div>群20:165796402(2000人已满)</div> -->
<div>群19:165657124(2000人已满)</div>
<div>群18:698592271(2000人已满)</div>
<div>群17:951348804(2000人已满)</div>
......@@ -95,7 +95,7 @@
<div>群9:775128777(2000人已满)</div>
<div>群8:695442854(2000人已满)</div>
<div>群7:942061423(2000人已满)</div>
<!-- <div>群6:697264024(2000人已满)</div> -->
<div>群6:697264024(2000人已满)</div>
<div>群5:731951419(2000人已满)</div>
<div>群4:942702595(2000人已满)</div>
<div>群3:773794803(2000人已满) </div>
......
### 屏幕适配指南
#### 宽屏适配指南
uni-app是以移动为先的理念诞生的。从uni-app 2.9起,提供了PC等宽屏的适配方案。
uni-app是以移动为先的理念诞生的。从uni-app 2.9起,提供了PC等宽屏的适配方案,完成了全端统一
PC适配和屏幕适配略有差异。PC适配包含`宽屏适配``uni-app内置组件适配PC`两方面的工作。
......@@ -14,17 +14,22 @@ uni-app提供的屏幕适配方案,包括3部分:
各个window之间可以交互通信。
这里有2个例子:
- 分栏式的新闻模块:[https://static-7d133019-9a7e-474a-b7c2-c01751f00ca5.bspapp.com/#/](https://static-7d133019-9a7e-474a-b7c2-c01751f00ca5.bspapp.com/#/),这个示例对应的源码在:[https://github.com/dcloudio/uni-template-news](https://github.com/dcloudio/uni-template-news)
- 分栏式的DCloud社区:[https://static-1afcc27f-ce2f-4a6d-9416-c65a6f87d24e.bspapp.com/#/](https://static-1afcc27f-ce2f-4a6d-9416-c65a6f87d24e.bspapp.com/#/)。这个示例只适配了首页。
- hello uni-app:[https://hellouniapp.dcloud.net.cn/](https://hellouniapp.dcloud.net.cn/)
- 分栏式的新闻模板:[https://static-7d133019-9a7e-474a-b7c2-c01751f00ca5.bspapp.com/#/](https://static-7d133019-9a7e-474a-b7c2-c01751f00ca5.bspapp.com/#/),这个示例对应的源码在:[https://github.com/dcloudio/uni-template-news](https://github.com/dcloudio/uni-template-news)
以上示例建议使用最新版的chrome、Safari、或firefox访问。可以在PC模式和手机模式分别体验。以上示例源码的运行需使用HBuilderX 2.9+
这些例子特点如下:
- 在宽屏下会新增rightWindow区域,用于显示详情页面,点击左边的列表在右边显示详情内容。而窄屏下仍然是点击列表后新开一个页面显示详情内容。
- rightWindow里的页面是复用的,不需要重写新闻详情页面,支持把已有详情页面当组件放到 rightWindow 页面中。
- hello uni-app使用了topWindow和leftWindow,分为上左右3栏。新闻模板使用了rightWindow区域,分为左右2栏。宽屏下点击左边的列表在右边显示详情内容。而窄屏下仍然是点击列表后新开一个页面显示详情内容。
- leftWindow或rightWindow 里的页面是复用的,不需要重写新闻详情页面,支持把已有详情页面当组件放到 leftWindow或rightWindow 页面中。
这套方案是已知的、最便捷的分栏式宽屏应用适配方案。
__H5 宽屏下 tabBar(选项卡) 与窗体的关系__
> 目前做如下调整:leftWindow、rightWindow、topWindow 中有其一存在,则 tabBar 隐藏;不存在,则隐藏。
leftWindow等配置,在pages.json里进行。文档见:[https://uniapp.dcloud.net.cn/collocation/pages?id=topwindow](https://uniapp.dcloud.net.cn/collocation/pages?id=topwindow)
pages.json 配置样例
......@@ -63,7 +68,7 @@ pages.json 配置样例
如果已经有了一个为小屏设计的uni-app,在使用leftWindow等窗体适配大屏时,需理清一个思路:现有的小屏内容,放在哪个window里?
比如上面的2个例子,都是双栏式窗体,左边列表、右边详情。此时适合的做法是,将原有的小屏列表作为主window,在右边扩展rightWindow来显示详情。
如果应用的首页是列表,二级页是详情,此时适合的做法是,将原有的小屏列表作为主window,在右边扩展rightWindow来显示详情。
以新闻示例项目为例,预览地址[https://static-7d133019-9a7e-474a-b7c2-c01751f00ca5.bspapp.com/#/](https://static-7d133019-9a7e-474a-b7c2-c01751f00ca5.bspapp.com/#/)。这个项目的源码已经内置于HBuilderX 2.9中,新建uni-app项目时选择新闻/资讯模板。
......@@ -117,7 +122,7 @@ goDetail(detail) {
uni.$emit('updateDetail', {
detail: encodeURIComponent(JSON.stringify(detail))
})
} else { // 若为窄,则打开新窗体,在新窗体打开详情页面
} else { // 若为窄,则打开新窗体,在新窗体打开详情页面
uni.navigateTo({
url: '/pages/detail/detail?query=' + encodeURIComponent(JSON.stringify(detail))
});
......@@ -134,9 +139,9 @@ leftWindow比较适合放置导航页面。如果你的应用首页有很多tab
leftWindow除了适用于手机应用适配大屏,也适用于重新开发的PC应用,尤其是PC Admin管理控制台。
这里有一个使用uni-app做PC Admin的例子:[https://github.com/dcloudio/uni-template-admin](https://github.com/dcloudio/uni-template-admin)
DCloud官方基于uni-app的pc版,推出了unicloud Admin:[https://uniapp.dcloud.net.cn/uniCloud/admin](https://uniapp.dcloud.net.cn/uniCloud/admin)
目前的leftWindow、rightWindow、topWindow 只支持H5端。计划后续在Pad App上实现该配置。小程序无法支持该配置。
目前的leftWindow、rightWindow、topWindow 只支持web端。计划后续在Pad App上实现该配置。小程序无法支持该配置。
#### 2. 组件级适配方案:match-media组件
......@@ -276,7 +281,7 @@ uni-app理论上不限定浏览器。在HBuilderX 2.9发版时,就新闻示例
如果你的h5版已经开发完毕,还没来得及适配pc,但想在pc上先用起来。那么可以在pc网页里使用iframe,约定好宽度,在里面套用uni-app的窄屏版。
当然还可以在iframe旁边放置二维码,提供手机版扫码地址,如下
当然还可以在iframe旁边放置二维码,提供手机版扫码地址,例如
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/979f7940-12ba-11eb-b680-7980c8a877b8.png)
......
......@@ -175,7 +175,7 @@
<img src="//img-cdn-qiniu.dcloud.net.cn/uniapp/doc/qq@2x.png" width="20" height="20"/>
<div class="contact-smg">
<div>官方QQ交流群</div>
<div>6:697264024 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=SP8-OAARtiYc3heIMYDBNfffG3I5utCy&jump_from=webapi">点此加入</a></div>
<div>20:165796402 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=2jQQukeVdbptonlHsWatgBN8Ef_pRdcj&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -191,7 +191,7 @@
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<div>群21:717019120(2000人已满)</div>
<div>群20:165796402(2000人已满)</div>
<!-- <div>群20:165796402(2000人已满)</div> -->
<div>群19:165657124(2000人已满)</div>
<div>群18:698592271(2000人已满)</div>
<div>群17:951348804(2000人已满)</div>
......@@ -205,7 +205,7 @@
<div>群9:775128777(2000人已满)</div>
<div>群8:695442854(2000人已满)</div>
<div>群7:942061423(2000人已满)</div>
<!-- <div>群6:697264024(2000人已满)</div> -->
<div>群6:697264024(2000人已满)</div>
<div>群5:731951419(2000人已满)</div>
<div>群4:942702595(2000人已满)</div>
<div>群3:773794803(2000人已满) </div>
......
......@@ -37,7 +37,7 @@ uni.onKeyboardHeightChange(res => {
#### uni.getSelectedTextRange(OBJECT)
在input、textarea等focus之后,获取输入框的光标位置。注意:只有在focus的时候调用此接口才有效。
在input、textarea等focus之后,获取输入框的光标位置。注意:只有在focus的时候调用此接口才有效。目前仅支持 vue 页面,nvue 可以直接使用 weex 的 [getSelectionRange](https://weex.apache.org/zh/docs/components/input.html#getSelectionRange)
**平台差异说明**
......
......@@ -12,8 +12,8 @@
- 客户端调用的js API见:[https://www.html5plus.org/doc/zh_cn/push.html](https://www.html5plus.org/doc/zh_cn/push.html)
- web自助发送界面:在DCloud的开发者后台:[https://dev.dcloud.net.cn/](https://dev.dcloud.net.cn/),选择应用后点击uniPush栏目。
- 编写代码调用服务器接口发送push消息:
* 如果使用uniCloud开发服务器,可以使用封装好的插件,更简单易用:[https://ext.dcloud.net.cn/plugin?id=1680](https://ext.dcloud.net.cn/plugin?id=1680)
* 如果使用传统服务器开发,文档仍然是个推的服务器文档[http://docs.getui.com/](http://docs.getui.com/)
* 如果使用uniCloud开发服务器,可以使用封装好的插件,更简单易用:[https://ext.dcloud.net.cn/plugin?id=1680](https://ext.dcloud.net.cn/plugin?id=1680)
* 如果使用传统服务器开发,文档仍然是个推的服务器文档[http://docs.getui.com/](http://docs.getui.com/)
**其他相关资源**
- 检查应用是否被授予推送权限:[https://ext.dcloud.net.cn/plugin?id=594](https://ext.dcloud.net.cn/plugin?id=594)
......@@ -35,18 +35,24 @@
### 小程序平台
小程序平台的类似概念叫做`模板消息`
小程序平台的类似概念叫做`模板消息`,也有的平台改名为`订阅消息`
以微信为例,开发者的服务器发送消息给微信的服务器,微信服务器会发送一条模板消息,折叠到微信的消息列表中的服务通知里。它属于后台开发,和手机端无关。
以微信为例,开发者的服务器发送消息给微信的服务器,微信服务器会发送一条订阅消息,折叠到微信的消息列表中的服务通知里。它属于后台开发,和手机端无关。
微信模板消息文档:[https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/template-message.html](https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/template-message.html)
如果使用uniCloud发送微信、支付宝订阅消息,参考:[https://ext.dcloud.net.cn/plugin?id=1810](https://ext.dcloud.net.cn/plugin?id=1810)
如果使用uniCloud发送微信模板消息,参考:[https://ext.dcloud.net.cn/plugin?id=1810](https://ext.dcloud.net.cn/plugin?id=1810)
微信订阅消息文档:[https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html](https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html)
支付宝模板消息文档:[https://docs.alipay.com/mini/introduce/message](https://docs.alipay.com/mini/introduce/message)
百度模板消息文档:[https://smartprogram.baidu.com/docs/develop/third/api/](https://smartprogram.baidu.com/docs/develop/third/api/)
字节跳动订阅消息文档:[https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/functional-plug-in/subscribemessage/](https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/functional-plug-in/subscribemessage/)
QQ小程序订阅消息文档:[https://q.qq.com/wiki/develop/miniprogram/frame/open_ability/open_message.html#%E8%AE%A2%E9%98%85%E6%B6%88%E6%81%AF](https://q.qq.com/wiki/develop/miniprogram/frame/open_ability/open_message.html#%E8%AE%A2%E9%98%85%E6%B6%88%E6%81%AF)
华为快应用推送文档:[https://developer.huawei.com/consumer/cn/doc/development/quickApp-References/webview-api-hwpush](https://developer.huawei.com/consumer/cn/doc/development/quickApp-References/webview-api-hwpush)
<!--
**注意:以下API暂停维护,仅为向下兼容而保留。App端 uni push 的API请使用 [https://www.html5plus.org/doc/zh_cn/push.html](https://www.html5plus.org/doc/zh_cn/push.html)**
......
......@@ -11,7 +11,7 @@
|data|Object/String/ArrayBuffer|否||请求的参数|App(自定义组件编译模式)不支持ArrayBuffer类型|
|header|Object|否||设置请求的 header,header 中不能设置 Referer。|H5端会自动带上cookie不可手动覆盖|
|method|String|否|GET|有效值详见下方说明||
|timeout|Number|否|30000|超时时间,单位 ms|H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序|
|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和支付宝小程序不支持|
|sslVerify|Boolean|否|true|验证 ssl 证书|仅App安卓端支持(HBuilderX 2.3.3+)|
......
### uni.onUIStyleChange(CALLBACK)
### uni.onThemeChange(CALLBACK)
监听系统主题状态变化。
**CALLBACK 返回参数**
|参数|类型|说明|平台差异说明|
|:-|:-|:-|:-|
|style|String|主题名称(dark, light)|App2.6.5+ 仅iOS|
|theme|String|主题名称(dark, light)|App2.6.5+ 仅iOS|
**示例**
```javascript
uni.onUIStyleChange(function (res) {
console.log(res.style);
uni.onThemeChange(function (res) {
console.log(res.theme);
});
```
......
......@@ -251,7 +251,7 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**中华英才网:** 百度小程序搜索“中华英才网”
<!-- **CSDN:** 微信小程序搜索“CSDN” -->
**CSDN App:** Appstore新闻类榜单前十。[uni小程序SDK](https://nativesupport.dcloud.net.cn)案例。App内部众多栏目做成小程序形式。[App下载](https://www.csdn.net/apps/download)
**开源中国:** 微信小程序搜索“osc+”、百度小程序搜索“开源中国社区”
......@@ -283,6 +283,8 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**中国移动咪咕商城:**[H5](https://mgmall.migudm.cn/)
**中国移动咪咕爱看App:** 内嵌[uni小程序SDK](https://nativesupport.dcloud.net.cn)。App内部部分栏目做成小程序形式。[Android](https://android.myapp.com/myapp/detail.htm?apkName=com.wondertek.miguaikan)[iOS](https://apps.apple.com/cn/app/id1168490851)
**中国移动微信平台个人中心**
**北京移动:**App部分页面使用uni-app制作
......
......@@ -53,7 +53,7 @@
<img src="//img-cdn-qiniu.dcloud.net.cn/uniapp/doc/qq@2x.png" width="20" height="20"/>
<div class="contact-smg">
<div>官方QQ交流群</div>
<div>6:697264024 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=SP8-OAARtiYc3heIMYDBNfffG3I5utCy&jump_from=webapi">点此加入</a></div>
<div>20:165796402 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=2jQQukeVdbptonlHsWatgBN8Ef_pRdcj&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -69,7 +69,7 @@
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<div>群21:717019120(2000人已满)</div>
<div>群20:165796402(2000人已满)</div>
<!-- <div>群20:165796402(2000人已满)</div> -->
<div>群19:165657124(2000人已满)</div>
<div>群18:698592271(2000人已满)</div>
<div>群17:951348804(2000人已满)</div>
......@@ -83,7 +83,7 @@
<div>群9:775128777(2000人已满)</div>
<div>群8:695442854(2000人已满)</div>
<div>群7:942061423(2000人已满)</div>
<!-- <div>群6:697264024(2000人已满)</div> -->
<div>群6:697264024(2000人已满)</div>
<div>群5:731951419(2000人已满)</div>
<div>群4:942702595(2000人已满)</div>
<div>群3:773794803(2000人已满) </div>
......
......@@ -297,7 +297,7 @@ Tips:`uni-app` 中 `manifest.json->h5->devServer` 实际上对应 `webpack`
"maps": {
"qqmap": {
//腾讯地图秘钥(key)
"key": "XVXBZ-NDMC4-JOGUS-XGIEE-QVHDZ-AMFV2"
"key": ""
}
}
}
......@@ -583,22 +583,12 @@ mp-qq只支持自定义组件模式,不存在usingComponents配置
"password": "iOS应用打包个人证书导入密码",
"p12": "iOS应用打包个人证书,打包配置文件关联的个人证书",
"devices": "iOS应用支持的设备类型,可取值iphone/ipad/universal",
"urltypes": [{
"urlschemes": [
"hbuilder",
"必选,程序所支持的自定义协议名称"
],
"id": "可选,自定义协议的标识",
"icon": "可选,打开程序时显示的图标"
},
"urltypes": [
{
"urlidentifier": "com.xxx.test",
"urlschemes": [
"http",
"https",
"必选,程序所支持的自定义协议名称,大小写无关,推荐使用小写"
],
"id": "可选,自定义协议的标识",
"icon": "可选,打开程序时显示的图标"
"hbuilder"// 必选,程序所支持的自定义协议名称
]
}
],
"frameworks": ["使用native.js调用API要引用的库文件名称,如CoreLocation.framework", "QuartzCore.framework"],
......
......@@ -155,12 +155,13 @@
|rpxCalcMaxDeviceWidth|Number|960|rpx 计算所支持的最大设备宽度,单位 px|App、H5(2.8.12+)|
|rpxCalcBaseDeviceWidth|Number|375|rpx 计算使用的基准设备宽度,设备实际宽度超出 rpx 计算所支持的最大设备宽度时将按基准宽度计算,单位 px|App、H5(2.8.12+)|
|rpxCalcIncludeWidth|Number|750|rpx 计算特殊处理的值,始终按实际的设备宽度计算,单位 rpx|App、H5(2.8.12+)|
|maxWidth|Number|1190|单位px,当浏览器可见区域宽度大于maxWidth时,两侧留白,当小于等于maxWidth时,页面铺满;不同页面支持配置不同的maxWidth;maxWidth = leftWindow(可选)+page(页面主体)+rightWindow(可选)|H5(2.9.9+)|
**注意**
- 支付宝小程序使用`titleImage`时必须使用`https`的图片链接地址,需要真机调试才能看到效果,支付宝开发者工具内无效果
- `globalStyle`中设置的`titleImage`也会覆盖掉`pages`->`style`内的设置文字标题
- 使用 `maxWidth` 时,页面内fixed元素需要使用--window-left,--window-right来保证布局位置正确
# topWindow@topwindow
......@@ -319,6 +320,11 @@ uni-app 2.9+ 新增 leftWindow, topWindow, rightWindow 配置。用于解决宽
|leftWindow|Boolean|true|当存在 leftWindow时,当前页面是否显示 leftWindow|H5|
|topWindow|Boolean|true|当存在 topWindow 时,当前页面是否显示 topWindow|H5|
|rightWindow|Boolean|true|当存在 rightWindow时,当前页面是否显示 rightWindow|H5|
|maxWidth|Number|1190|单位px,当浏览器可见区域宽度大于maxWidth时,两侧留白,当小于等于maxWidth时,页面铺满;不同页面支持配置不同的maxWidth;maxWidth = leftWindow(可选)+page(页面主体)+rightWindow(可选)|H5(2.9.9+)|
**注意**
- 使用 `maxWidth` 时,页面内fixed元素需要使用--window-left,--window-right来保证布局位置正确
**代码示例:**
......@@ -884,8 +890,8 @@ h5 平台下拉刷新动画,只有 circle 类型。
- `easycom`方式引入组件不是全局引入,而是局部引入。例如在H5端只有加载相应页面才会加载使用的组件
- 在组件名完全一致的情况下,`easycom`引入的优先级低于手动引入(区分连字符形式与驼峰形式)
- 考虑到编译速度,直接在`pages.json`内修改`easycom`不会触发重新编译,需要改动页面内容触发。
- `easycom`只处理vue组件,不处理小程序组件。暂不处理后缀为.nvue的组件,建议参考uni ui,使用vue后缀,同时兼容nvue页面。
- `nvue`页面里`.vue`后缀的组件,同样支持`easycom`
- `easycom`只处理vue组件,不处理小程序专用组件(如微信的wxml格式组件)。不处理后缀为.nvue的组件。但vue组件也可以全端运行,包括小程序和app-nvue。可以参考uni ui,使用vue后缀,同时兼容nvue页面。
- `nvue`页面里引用`.vue`后缀的组件,会按照nvue方式使用原生渲染,其中不支持的css会被忽略掉。这种情况同样支持`easycom`
# tabBar
如果应用是一个多 tab 应用,可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页。
......
......@@ -126,7 +126,7 @@
<img src="//img-cdn-qiniu.dcloud.net.cn/uniapp/doc/qq@2x.png" width="20" height="20"/>
<div class="contact-smg">
<div>官方QQ交流群</div>
<div>6:697264024 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=SP8-OAARtiYc3heIMYDBNfffG3I5utCy&jump_from=webapi">点此加入</a></div>
<div>20:165796402 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=2jQQukeVdbptonlHsWatgBN8Ef_pRdcj&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -142,7 +142,7 @@
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<div>群21:717019120(2000人已满)</div>
<div>群20:165796402(2000人已满)</div>
<!-- <div>群20:165796402(2000人已满)</div> -->
<div>群19:165657124(2000人已满)</div>
<div>群18:698592271(2000人已满)</div>
<div>群17:951348804(2000人已满)</div>
......@@ -156,7 +156,7 @@
<div>群9:775128777(2000人已满)</div>
<div>群8:695442854(2000人已满)</div>
<div>群7:942061423(2000人已满)</div>
<!-- <div>群6:697264024(2000人已满)</div> -->
<div>群6:697264024(2000人已满)</div>
<div>群5:731951419(2000人已满)</div>
<div>群4:942702595(2000人已满)</div>
<div>群3:773794803(2000人已满) </div>
......
......@@ -65,17 +65,15 @@ App和微信小程序的ad组件没有type属性,可以用于banner,也可
**注意**
- `<ad>` 组件是原生组件,在webview页面会有层级问题,同时无法在`<swiper>``<scroll-view>` 组件中使用。但app-nvue、微信小程序新版和头条小程序新版支持同层渲染,所以没有层级问题。而app-vue、QQ小程序等平台则有层级问题。详见:[原生组件](https://uniapp.dcloud.io/component/native-component)
- 无广告时没有高度,关闭广告时释放高度,宽度由父容器决定
- App 平台,因广告组件内部获得广告数据计算后设置组件大小,会出现界面抖动问题,可以提前通过 plus.ad.getAds 获得广告数据,设置 data 后 adpid 将无效
- 微信小程序 `<ad>` 组件不支持触发 tap 等触摸相关事件
- Android 平台 nvue的 `<list>` 组件中使用 `<ad>` 时,必须指定宽度属性`<ad width="750rpx" />`,因为 `<list>` 有自动的内存回收机制,不在屏幕范围的组件不被创建,组件内部无法获取大小
- app-nvue 的 `<recycle-list>` 组件内不支持嵌套 `<ad>`
- 广点通概率出现重复广告,可根据需求请求广告数据,推荐单次大于1条(plus.ad.getAds) 来降低重复率
- app-vue 页面使用 `<ad>` 不支持非 V3 编译,必须使用v3编译器。
- `<recycle-list>` 暂不支持 `<ad>`
- app-vue|QQ是客户端[原生组件](https://uniapp.dcloud.io/component/native-component),层级最高无法被覆盖,app-nvue|微信|头条没有层级覆盖问题
- app-vue 无法在 `<swiper>` 组件中使用`<ad>`
- app-vue 不能在 `<scroll-view>` 组件中使用 `<ad>`,仅适用于页面级的滚动
- HBuilderX2.8+版本Android平台更新穿山甲(今日头条)广告SDK后不再支持x86类型CPU,无法运行到x86类型cpu的模拟器。
- app-vue 页面使用 `<ad>` 必须使用v3编译器。如果使用HBuilderX 2.7以下版本,需注意开启v3编译模式。2.7以上版本已经淘汰了其他模式,无需关心本条。
- `<ad>` 组件测试广告位是上图下文,uniAD后台申请的广告位默认左图右文
- HBuilderX标准基座真机运行测试信息流广告位标识(adpid)为:1111111111
......
......@@ -28,7 +28,7 @@
|@getuserinfo|Handler||用户点击该按钮时,会返回获取到的用户信息,从返回参数的detail中获取到的值同uni.getUserInfo|open-type="getUserInfo"|微信小程序|
|@error|Handler||当使用开放能力时,发生错误的回调|open-type="launchApp"|微信小程序|
|@opensetting|Handler||在打开授权设置页并关闭后回调|open-type="openSetting"|微信小程序|
|@launchapp|Handler||打开 APP 成功的回调|open-type="launchApp"|微信小程序|
|@launchapp|Handler||从小程序打开 App 成功的回调|open-type="launchApp"|微信小程序|
- **注1:``button-hover`` 默认为 ``{background-color: rgba(0, 0, 0, 0.1); opacity: 0.7;}``**
- ```open-type="launchApp"```时需要调起的APP接入微信OpenSDK[详见](https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/launchApp.html)
......@@ -64,13 +64,41 @@
|getUserInfo|获取用户信息,可以从@getuserinfo回调中获取到用户信息,包括头像、昵称等信息|微信小程序、百度小程序、QQ小程序|
|contact | 打开客服会话,如果用户在会话中点击消息卡片后返回应用,可以从 @contact 回调中获得具体信息 |微信小程序、百度小程序|
|getPhoneNumber | 获取用户手机号,可以从@getphonenumber回调中获取到用户信息|微信小程序、百度小程序、字节跳动小程序、支付宝小程序 |
|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)|
|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 | 支持小程序授权 | 支付宝小程序 |
|contactShare | 分享到通讯录好友 | 支付宝小程序 |
|lifestyle | 关注生活号 | 支付宝小程序 |
|openGroupProfile|呼起QQ群资料卡页面,可以通过group-id属性设定需要打开的群资料卡的群号,同时manifest中必须配置groupIdList|QQ小程序基础库1.4.7版本+|
**button点击**
button 组件的点击遵循 vue 标准的 @click事件。
button 组件没有 url 属性,如果要跳转页面,可以在@click中编写,也可以在button组件外面套一层 navigator 组件。举例,如需跳转到about页面,可按如下几种代码写法执行:
```html
<template>
<view>
<navigator url="/pages/about/about"><button type="default">通过navigator组件跳转到about页面</button></navigator>
<button type="default" @click="goto('/pages/about/about')">通过方法跳转到about页面</button>
<button type="default" @click="navigateTo('/pages/about/about')">跳转到about页面</button><!-- 这种写法只有h5平台支持,不跨端,不推荐使用 -->
</view>
</template>
<script>
export default {
methods: {
goto(url) {
uni.navigateTo({
url:url
})
}
}
}
</script>
```
**注意**
- 在小程序中,开发者可以登录 [微信小程序管理后台](https://mp.weixin.qq.com/)[QQ小程序后台](https://q.qq.com/#/)后,进入菜单“客服反馈”页面获取反馈内容。
- 在 App 中,开发者登录 [DCloud开发者中心](https://dev.dcloud.net.cn/) 后点击应用名称,进入左侧菜单“用户反馈”页面获取反馈内容。
......
#### custom-tab-bar
自定义tabBar。
该组件目前支持 ``pages.json````tabBar`` 相关配置(兼容性和 H5 保持一致), 其中不支持 ``borderStyle`` 配置
该组件保留了原生 ``tabBar`` 相关功能,例如设置 tab 徽标、显示红点等,支持所有 ``tabBar`` 相关 API。
**使用场景**
适用于 PC 宽屏适配等场景,可用 custom-tab-bar 组件将原来的 tabBar 的功能和逻辑快速转换为网页顶部的导航或侧边栏(见文章尾部截图),实现快速适配 pc 网页,当页面路由跳转到tabBar页面时,自动高亮。
**平台兼容性**
__仅 H5 支持__,HBuilderX 2.9.9 + 。
**属性说明**
|属性名|类型|默认值|说明|
|:-|:-|:-|:-|
|direction|String|horizontal|选项的排列方向 可选值:horizontal,vertical|
|show-icon|Boolean|false|是否显示icon|
|selected|Number|0|选中的tabBar选项索引值|
|onTabItemTap|EventHandle||点击事件,参数为Object,具体见下表|
``onTabItemTap`` 参数说明:
|属性|类型|说明|
|---|---|---|
|index|String|被点击tabItem的序号,从0开始|
|pagePath|String|被点击tabItem的页面路径|
|text|String|被点击tabItem的按钮文字|
**示例**
如下为`hello uni-app`中的源码示例,展现效果见下方截图:
```html
<!-- 本示例未包含完整css,获取外链css请参考上文,在hello uni-app项目中的 top-window 查看 -->
<template>
<view>
<custom-tab-bar direction="horizontal" :show-icon="false" :selected="selected" @onTabItemTap="onTabItemTap" />
</view>
</template>
```
custom-tab-bar 水平布局(horizontal):
![uniapp](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/5dc930c0-2580-11eb-8a36-ebb87efcf8c0.png)
custom-tab-bar 竖直布局(vertical):
![uniapp](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b3b68450-2595-11eb-880a-0db19f4f74bb.png)
......@@ -97,6 +97,15 @@
![uniapp](https://img-cdn-qiniu.dcloud.net.cn/uniapp/doc/img/form.png?t=201857)
**Tips**
- 为方便做表单验证,uni ui提供了`<uni-forms>`组件,参考:[https://ext.dcloud.net.cn/plugin?id=2773](https://ext.dcloud.net.cn/plugin?id=2773)
- 如果使用uniCloud,其数据库提供了`DB Schema`,在schema中配置字段的格式,前端表单校验和服务器入参校验将可以复用该规则,无需在两端重复开发。[详见](https://uniapp.dcloud.io/uniCloud/schema)
- 有很多表单自助生成辅助工具
* 如果使用uniCloud的`DB Schema`可以自动生成全套表单,包括界面、校验逻辑、提交入库,[详见](https://uniapp.dcloud.io/uniCloud/schema?id=autocode).
* 不使用uniCloud的话,插件市场有可视化拖拽表单插件:[详见](https://ext.dcloud.net.cn/search?q=%E5%8F%AF%E8%A7%86%E5%8C%96)。这类插件只生成界面,没有逻辑。
**使用内置 behaviors**
小程序端在`form`内的自定义组件内有`input`表单控件时,或者用普通标签实现表单控件,例如``评分``等,无法在`form``submit`事件内获取组件内表单控件值,此时可以使用`behaviors`
......@@ -173,6 +182,3 @@ uni://form-field
</style>
```
**tips**
- [插件市场](http://ext.dcloud.net.cn/search?q=%E8%A1%A8%E5%8D%95%E6%A0%A1%E9%AA%8C)有表单校验插件
......@@ -33,7 +33,7 @@ mode 有 13 种模式,其中 4 种是缩放模式,9 种是裁剪模式。
|缩放|aspectFit|保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。|
|缩放|aspectFill|保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。|
|缩放|widthFix|宽度不变,高度自动变化,保持原图宽高比不变|
|缩放|heightFix|高度不变,宽度自动变化,保持原图宽高比不变 **App 和 H5 平台 2.8.9+ 支持、微信小程序需要基础库 2.10.3**|
|缩放|heightFix|高度不变,宽度自动变化,保持原图宽高比不变 **App 和 H5 平台 HBuilderX 2.9.3+ 支持、微信小程序需要基础库 2.10.3**|
|裁剪|top|不缩放图片,只显示图片的顶部区域|
|裁剪|bottom|不缩放图片,只显示图片的底部区域|
|裁剪|center|不缩放图片,只显示图片的中间区域|
......
......@@ -127,7 +127,7 @@ args 为要设置的参数为json类型可以包含下列元素
属性|类型 |默认值|必填|说明
:--|:--|:--|:--|:--|
id|string|无|是|和list同时滚动的组件id,应为外层的scroller
headerHeight|float|0|是|要吸顶的header顶部距离scroller顶部的距离
headerHeight|float|0|是|要吸顶的header顶部距离scroller顶部的距离,Android暂不支持
#####返回值:无
......
......@@ -2,7 +2,7 @@
从底部弹起的滚动选择器。支持五种选择器,通过mode来区分,分别是普通选择器,多列选择器,时间选择器,日期选择器,省市区选择器,默认是普通选择器。
**普通选择器**
#### 普通选择器
``mode = selector``
......@@ -20,7 +20,7 @@
- picker在各平台的实现是有UI差异的,有的平台如百度、支付宝小程序的Android端是从中间弹出的;有的平台支持循环滚动如百度小程序;有的平台没有取消按钮如App-iOS端。但均不影响功能使用。
**多列选择器**
#### 多列选择器
``mode = multiSelector``
......@@ -48,7 +48,7 @@
- 由于 JavaScript 的限制 vue 不能观测如下方式设置 value:``this.value[0] = 0``[vue 注意事项](https://cn.vuejs.org/v2/guide/list.html#注意事项)),解决方式参考:[hello-uniapp 示例](https://github.com/dcloudio/hello-uniapp/commit/59264474172a591c865431d02a2a1e3583978827)
- 微信开发工具的pc模拟器有可能出现拖动数据错乱,使用真机正常
**时间选择器**
#### 时间选择器
``mode = time``
......@@ -71,7 +71,7 @@
|@cancel|EventHandle||取消选择时触发||
|disabled|Boolean|false|是否禁用|&nbsp;|
**日期选择器**
#### 日期选择器
``mode = date``
......@@ -103,7 +103,7 @@
|month|选择器粒度为月份|
|day|选择器粒度为天|
**省市区选择器**
#### 省市区选择器
``mode = region``
......
......@@ -42,6 +42,8 @@
**App初期启动的引导轮播:** 因为是App专用,为了更好的性能,推荐使用nvue制作。参考插件市场已经封装的插件[https://ext.dcloud.net.cn/plugin?id=676](https://ext.dcloud.net.cn/plugin?id=676)
**iOS平台适配暗黑模式(DarkMode):**[https://ask.dcloud.net.cn/article/36995](https://ask.dcloud.net.cn/article/36995)
**原生App和uni-app混合开发:** [详见](hybrid)
## H5常见问题
......
......@@ -37,7 +37,7 @@
</pre>
**Tips**
- 编译到任意平台时,`static` 目录下的文件均会被打包进去,非 `static` 目录下的文件(vue、js、css 等)被引用到才会被包含进去。
- `static` 目录下的 `js` 文件不会被编译,如果里面有 `es6` 的代码,不经过转换直接运行,在手机设备上会报错。
- `css`、`less/scss` 等资源同样不要放在 `static` 目录下,建议这些公用的资源放在 `common` 目录下。
- HbuilderX 1.9.0+ 支持在根目录创建 `ext.json` `sitemap.json` 文件。
......
......@@ -93,6 +93,7 @@ app-nvue和h5不存在此问题。造成差异的原因是小程序目前只提
##### 长列表
- 长列表中如果每个item有一个点赞按钮,点击后点赞数字+1,此时点赞组件必须是一个单独引用的组件,才能做到差量数据更新。否则会造成整个列表数据重载。
- 长列表中每个item并不一定需要做成组件,取决于你的业务中是否需要差量更新某一行item的数据,如没有此类需求则不应该引入大量组件。(点击item后背景变色,属于css调整,没有更新data数据和渲染,不涉及这个问题)
- 单个组件中存在大量数据时(比如长列表),在App和小程序端数据更新时会消耗较多时间,建议使用组件对数据进行分页,将变更限制更小范围。可以参考:[长列表优化示例](https://ext.dcloud.net.cn/plugin?id=2863#detail)
- app端nvue的长列表应该使用list组件,有自动的渲染资源回收机制。vue页面使用页面滚动的性能,好于使用scroll-view的区域滚动。uni ui封装了uList组件,在app-nvue下使用了list组件,在其他环境使用页面滚动,自动适配,强烈推荐开发者使用,避免自己写的不好产生性能问题。
- 如需要左右滑动的长列表,请在HBuilderX新建uni-app项目选新闻模板,那是一个标杆实现。自己用swiper和scroll-view做很容易引发性能问题。
......
#### 2.9.6.20201031-alpha
+ 【重要】 更新文档 2.9.0+ 后 rpx、rem 样式变形的处理办法 [详情](https://ask.dcloud.net.cn/article/37911)
+ App平台、H5平台 新增 支持 uni.offCompassChange、uni.offAccelerometerChange 用于移除相关事件监听
+ App平台 优化 uni.connectSocket 支持配置 header
+ App-Android平台 修复 部分设备 uni.chooseVideo 无法选择视频的Bug [详情](https://ask.dcloud.net.cn/question/109301)
+ App-Android平台 修复 nvue map 组件 markers 的 width、height属性不生效的bug [详情](https://ask.dcloud.net.cn/question/108778)
+ App-Android平台 修复 nvue map 组件 translateMarker 方法中 rotate 参数值设置 `px` 单位后无法正常执行的Bug [详情](https://ask.dcloud.net.cn/question/109630)
+ App-Android平台 修复 2.9.5版本引出的 nvue 部分组件 border-radius 属性设置圆角无效的Bug [详情](https://ask.dcloud.net.cn/question/109597)
+ App-iOS平台 修复 iOS14 上新页面自动获取焦点导致页面变形的Bug [详情](https://ask.dcloud.net.cn/question/107820)
+ App-iOS平台 修复 nvue web-view 组件加载 html 页面中 js 调用 alert 不显示提示框的Bug [详情](https://ask.dcloud.net.cn/question/109791)
+ H5平台 优化 鼠标事件支持返回坐标信息
+ H5平台 优化 uni.showToast 在 宽屏的显示效果
+ H5平台 优化 弹出类接口和组件支持响应 esc、enter 按键
+ H5平台 修复 启用 leftWindow 后 web-view 组件显示错位的Bug
* 【uniCloud】
+ 新增 `<uni-clientDB>`组件支持remove方法,封装了删除确认框、删除数据库、删除前端data等操作,开发更便利 [详情](https://uniapp.dcloud.io/uniCloud/uni-clientdb-component?id=%e6%96%b9%e6%b3%95)
+ 优化 提升云函数执行速度几十毫秒。非冷启动时与传统服务器性能拉齐(需重新部署云函数)
* 【App插件(含5+App和uni-app的App端)】
+ Android平台 修复 uni-AD 腾讯广点通视频开屏广告可能造成应用闪退,或关闭广告后点击屏幕部分区域仍然打开落地页的Bug
+ Android平台 修复 UniPush 云端打包 GooglePlay 渠道默认添加定位权限的Bug [详情](https://ask.dcloud.net.cn/question/105068)
+ iOS平台 新增 二维码扫码支持 autoDecodeCharset 参数,解决非UTF-8编码数据出现乱码的问题 [详情](https://ask.dcloud.net.cn/question/66886)
+ iOS平台 修复 微信登录用户选择拒绝授权可能不触发失败回调的Bug [详情](https://ask.dcloud.net.cn/question/109305)
+ iOS平台 修复 无法保存文件路径包含中文的图片到系统相册的Bug [详情](https://ask.dcloud.net.cn/question/109168)
#### 2.9.5.20201024-alpha
+ App平台、H5平台 修复 Safari 14 输入组件禁用状态文字颜色变浅的Bug [详情](https://ask.dcloud.net.cn/question/109013)
+ App平台 新增 全屏视频 uni.createFullScreenVideoAd [详情](https://uniapp.dcloud.net.cn/api/a-d/full-screen-video)
......@@ -12,13 +36,13 @@
+ H5平台 修复 Chrome 使用自动填充时 placeholder 仍然可见的Bug
+ uni-ui 新增 uni-forms 组件,支持表单校验 [详情](https://ext.dcloud.net.cn/plugin?id=2773)
+ uni-ui 新增 uni-group 组件,用于表单项分组显示 [详情](https://ext.dcloud.net.cn/plugin?id=3281)
+ uni-ui 新增 uni-table 组件 [详情](https://ext.dcloud.net.cn/plugin?id=2773)
+ uni-ui 新增 uni-table 组件 [详情](https://ext.dcloud.net.cn/plugin?id=3270)
+ uni-ui 新增 uni-dateformat 组件,支持各种日期格式化,以及1分钟前、刚刚等形式 [详情](https://ext.dcloud.net.cn/plugin?id=3279)
* 【uniCloud】
+ 【重要】新增 clientDB 支持 `jql` 查询语法,大幅降低数据库操作难度 [详情](https://uniapp.dcloud.net.cn/uniCloud/database?id=jsquery)、大幅简化联表查询 [详情](https://uniapp.dcloud.net.cn/uniCloud/database?id=lookup)
+ 【重要】新增 clientDB 支持 `jql` 查询语法,大幅降低数据库操作难度 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=jsquery)、大幅简化联表查询 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=lookup)
+ 【重要】新增 uni-clientDB 组件,在前端通过组件直接获得云数据库内容,并直接绑定到界面上,大幅提升开发效率 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-clientdb-component)
+ 【重要】调整 clientDB内置,云端不再需要单独的clientDB云函数,前端无需引用clientDB的js sdk,直接在前端写`const db = uniCloud.database()`即可 [详情](https://uniapp.dcloud.net.cn/uniCloud/database)
+ 【重要】调整 uni-clientDB-actions 目录调整到 cloudfunctions 根目录 [详情](https://uniapp.dcloud.net.cn/uniCloud/database?id=action)
+ 【重要】调整 clientDB内置,云端不再需要单独的clientDB云函数,前端无需引用clientDB的js sdk,直接在前端写`const db = uniCloud.database()`即可 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb)
+ 【重要】调整 uni-clientDB-actions 目录调整到 cloudfunctions 根目录 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=action)
+ 【重要】调整 clientDB云函数的permission和validator子目录废除,只需在 DB Schema 中书写permission和validator内容,保存即可直接生效,无需再次导出
+ 【重要】新增 `uniCloud Admin 基础框架`(HBuilderX新建项目可选择该模板) [详情](https://uniapp.dcloud.net.cn/uniCloud/admin)
+ 【重要】新增 web控制台 云数据库配置 DB Schema 后,可直接生成前端工程,含数据表单新增、修改页面,以及校验规则。大幅提升开发效率
......@@ -91,7 +115,7 @@
+ 【重要】新增 match-media 媒体查询适配组件,用于动态屏幕适配 [详情](https://uniapp.dcloud.net.cn/component/match-media)
+ 新增 支持 uni.createMediaQueryObserver 方法 [详情](https://uniapp.dcloud.net.cn/api/ui/media-query-observer)
+ 【重要】App平台、H5平台 新增 rpx 配置,默认限定了 rpx 生效的最大屏幕宽度为 px。可在 pages.json -> globalStyle 配置 rpxCalcMaxDeviceWidth、rpxCalcBaseDeviceWidth、rpxCalcIncludeWidth 等参数 [详情](https://uniapp.dcloud.io/collocation/pages?id=globalstyle)
+ 【重要】App平台、H5平台 优化 调整根字体大小为系统默认大小与微信小程序平台一致
+ 【重要】App平台、H5平台 优化 调整根字体大小为系统默认大小与微信小程序平台一致 [详情](https://ask.dcloud.net.cn/article/37911)
+ App平台、H5平台 新增 支持 uni.getSelectedTextRange 方法 [详情](https://uniapp.dcloud.io/api/key?id=getselectedtextrange)
+ App平台、H5平台 修复 部分 base64 路径的图像无法显示的Bug [详情](https://ask.dcloud.net.cn/question/106591)
+ App平台 修复 weex 编译模式 vue 页面中的 picker 组件 change 事件有时无法触发的Bug [#1774](https://github.com/dcloudio/uni-app/issues/1774)
......
#### 2.9.8.20201110
+ App-Android平台 修复 uni原生插件扩展Component组件 bindData 回调不触发的Bug
+ App-iOS平台 修复 input 组件在点击时取消禁用无法弹出软键盘的Bug [详情](https://ask.dcloud.net.cn/question/110491)
* 【App插件(含5+App和uni-app的App端)】
+ iOS平台 修复 2.8.13版本引出的 高德定位设置 geocode 为 true 无法返回地址信息的Bug [详情](https://ask.dcloud.net.cn/question/110474)
#### 2.9.7.20201106
+ 【重要】 更新文档 2.9.0+ 后 rpx、rem 样式变形的处理办法 [详情](https://ask.dcloud.net.cn/article/37911)
+ App平台、H5平台 新增 支持 uni.offCompassChange、uni.offAccelerometerChange 用于移除相关事件监听
+ App平台、H5平台 修复 Safari 14 输入组件禁用状态文字颜色变浅的Bug [详情](https://ask.dcloud.net.cn/question/109013)
+ App平台 新增 全屏视频 uni.createFullScreenVideoAd [详情](https://uniapp.dcloud.net.cn/api/a-d/full-screen-video)
+ App平台 优化 uni.connectSocket 支持配置 header
+ App-Android平台 修复 uni.request 请求 cookie 与 X5 内核 webview 页面没有同步共享的Bug [详情](https://ask.dcloud.net.cn/question/108639)
+ App-Android平台 修复 nvue image 组件 mode 设置为 widthFix、heightFix 不生效的Bug
+ App-Android平台 修复 nvue map 组件使用 translateMarker 移动 maker 后气泡文本没有跟随移动的Bug [详情](https://ask.dcloud.net.cn/question/95239)
+ App-Android平台 修复 nvue map 组件动态删除 marker 的 callout 属性不生效的Bug
+ App-Android平台 修复 部分设备 uni.chooseVideo 无法选择视频的Bug [详情](https://ask.dcloud.net.cn/question/109301)
+ App-Android平台 修复 nvue map 组件 markers 的 width、height属性不生效的bug [详情](https://ask.dcloud.net.cn/question/108778)
+ App-iOS平台 修复 canvas 组件绘制 uni.getImageInfo 临时路径跨域的Bug [详情](https://ask.dcloud.net.cn/question/108817)
+ App-iOS平台 修复 nvue scroll-view 组件使用下拉刷新 refresh 隐藏时没有动画效果的Bug [详情](https://ask.dcloud.net.cn/question/108681)
+ App-iOS平台 修复 nvue image 组件 mode 设置为 widthFix、heightFix 时透明区域填充红色背景的Bug [详情](https://ask.dcloud.net.cn/question/108774)
+ App-iOS平台 修复 web-view 组件加载的页面 title 为空时,返回按钮不显示的Bug [详情](https://ask.dcloud.net.cn/question/108887)
+ App-iOS平台 修复 iOS14 上新页面自动获取焦点导致页面变形的Bug [详情](https://ask.dcloud.net.cn/question/107820)
+ App-iOS平台 修复 nvue web-view 组件加载 html 页面中 js 调用 alert 不显示提示框的Bug [详情](https://ask.dcloud.net.cn/question/109791)
+ H5平台 优化 鼠标事件支持返回坐标信息
+ H5平台 优化 uni.showToast 在 宽屏的显示效果
+ H5平台 优化 弹出类接口和组件支持响应 esc、enter 按键
+ H5平台 修复 Chrome 使用自动填充时 placeholder 仍然可见的Bug
+ H5平台 修复 启用 leftWindow 后 web-view 组件显示错位的Bug
+ uni-ui 新增 uni-forms 组件,支持表单校验 [详情](https://ext.dcloud.net.cn/plugin?id=2773)
+ uni-ui 新增 uni-group 组件,用于表单项分组显示 [详情](https://ext.dcloud.net.cn/plugin?id=3281)
+ uni-ui 新增 uni-table 组件 [详情](https://ext.dcloud.net.cn/plugin?id=3270)
+ uni-ui 新增 uni-dateformat 组件,支持各种日期格式化,以及1分钟前、刚刚等形式 [详情](https://ext.dcloud.net.cn/plugin?id=3279)
* 【uniCloud】
+ 【重要】新增 uni-clientDB 组件,在前端通过组件直接获得云数据库内容,并直接绑定到界面上,大幅提升开发效率 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-clientdb-component)
+ 【重要】新增 clientDB 支持 `jql` 查询语法,大幅降低数据库操作难度 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=jsquery)、大幅简化联表查询 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=lookup)
+ 【重要】调整 clientDB内置,云端不再需要单独的clientDB云函数,前端无需引用clientDB的js sdk,直接在前端写`const db = uniCloud.database()`即可 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb)
+ 【重要】调整 uni-clientDB-actions 目录调整到 cloudfunctions 根目录 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=action)
+ 【重要】调整 clientDB云函数的permission和validator子目录废除,只需在 DB Schema 中书写permission和validator内容,保存即可直接生效,无需再次导出
+ 【重要】新增 `uniCloud Admin 基础框架`(HBuilderX新建项目可选择该模板) [详情](https://uniapp.dcloud.net.cn/uniCloud/admin)
+ 【重要】新增 web控制台 云数据库配置 DB Schema 后,可直接生成前端工程,含数据表单新增、修改页面,以及校验规则。大幅提升开发效率。 [详情](https://uniapp.dcloud.net.cn/uniCloud/schema)
+ 【重要】腾讯云 正式商用 [详见](https://uniapp.dcloud.net.cn/uniCloud/price)
+ 优化 提升云函数执行速度几十毫秒。非冷启动时与传统服务器性能拉齐(需重新部署云函数)
+ 新增 web控制台 云数据库支持导出db_init.json
+ 新增 web控制台 服务空间改名
+ 新增 web控制台 云数据库支持`扩展校验函数`,可自主编程实现更复杂的数据校验逻辑,同时在 DB Schema 中引用这些`扩展校验函数`
+ 修复 阿里云 数据库set方法表现不正确的Bug
+ uni-id 新增 开发者callFunction时可自行传入uniIdToken,此时不再从storage获取token
* 【App插件(含5+App和uni-app的App端)】
+ 新增 uni-AD 支持全屏视频广告 [详情](https://ask.dcloud.net.cn/article/36718#fullscreenvideo)
+ 新增 二维码扫码支持 autoDecodeCharset 参数,解决非UTF-8编码数据出现乱码的问题 [详情](https://ask.dcloud.net.cn/question/66886)
+ 优化 uni-AD 基础开屏广告显示效果,适配各种分辨率屏幕设备
+ Android平台 更新 高德地图SDK为7.6.0版
+ Android平台 更新 uni-AD 快手联盟SDK为3.3.4.2版
+ Android平台 修复 uni-AD 腾讯广点通视频开屏广告可能造成应用闪退,或关闭广告后点击屏幕部分区域仍然打开落地页的Bug
+ Android平台 修复 uni-AD 应用从后台切换到前台显示开屏广告时,系统状态栏可能遮挡跳过按钮的Bug
+ Android平台 修复 多次调用二维码扫码时,因复用扫码提示音频播放对象导致概率闪退的Bug [详情](https://ask.dcloud.net.cn/question/108776)
+ Android平台 修复 获取屏幕亮度 getBrightness 在小米手机上可能返回数据异常的Bug [详情](https://ask.dcloud.net.cn/question/108691)
+ Android平台 修复 storage 存储数据内容超过 2M 后可能无法正常存取非ASCII字符的Bug
+ Android平台 修复 UniPush 云端打包 GooglePlay 渠道默认添加定位权限的Bug [详情](https://ask.dcloud.net.cn/question/105068)
+ Android平台 修复 Geolocation 定位模块默认添加后台定位权限 ACCESS_BACKGROUND_LOCATION 的Bug [详情](https://ask.dcloud.net.cn/question/109442)
+ iOS平台 更新 uni-AD 快手联盟SDK为3.3.3版
+ iOS平台 更新 云端打包环境XCode为12.1版,uni原生插件兼容支持swift代码
+ iOS平台 修复 微信登录用户选择拒绝授权可能不触发失败回调的Bug [详情](https://ask.dcloud.net.cn/question/109305)
+ iOS平台 优化 本地相册选择照片界面,新增支持 permissionAlert 参数配置权限检测,适配 iOS14 上用户设置为访问`选中的照片`权限时引导修改为访问`所有照片` [文档](http://www.html5plus.org/doc/zh_cn/gallery.html#plus.gallery.GalleryOptions)
+ iOS平台 修复 本地相册选择照片界面,在 iOS14 上如果选中的图片在 iCloud 会触发刷新导致排序混乱的Bug [详情](https://ask.dcloud.net.cn/question/108502)
+ iOS平台 修复 本地相册选择照片界面,选择视频文件出现错误提示框,预览视频文件只显示首帧的Bug
+ iOS平台 修复 本地相册选择照片界面,设置 filename 参数后选中多张图片后返回路径不正确的Bug
+ iOS平台 修复 无法保存文件路径包含中文的图片到系统相册的Bug [详情](https://ask.dcloud.net.cn/question/109168)
+ iOS平台 修复 获取当前地理位置设置 geocode 为 true 时可能无法返回数据的Bug [详情](https://ask.dcloud.net.cn/question/109170)
+ iOS平台 修复 获取图片信息 getImageInfo 返回的 width、height 值类型不正确的Bug [详情](https://ask.dcloud.net.cn/question/108893)
+ iOS平台 修复 视频播放控件横向全屏时唤起软键盘还是竖屏模式的Bug [详情](https://ask.dcloud.net.cn/question/107036)
+ iOS平台 修复 蓝牙订阅特征值 notifyBLECharacteristicValueChange 方法设置 state 属性不生效的Bug
+ iOS平台 修复 蓝牙同时读取和订阅特征值可能引起数据返回混乱的Bug [详情](https://ask.dcloud.net.cn/question/108107)
+ iOS平台 修复 Webview窗口标题栏搜索框的光标在 iOS13+ 上显示位置不正确的Bug [详情](https://ask.dcloud.net.cn/question/103205)
#### 2.9.3.20201014
+ 【重要】新增 大屏适配指南 [详情](https://uniapp.dcloud.net.cn/adapt)
+ 【重要】新增 leftWindow、rightWindow、topWindow,用于宽屏适配 [详情](https://uniapp.dcloud.net.cn/collocation/pages?id=topwindow)
......
......@@ -6,9 +6,10 @@
* [数据库](uniCloud/concepts/database.md)
* [云函数](uniCloud/concepts/cloudfunction.md)
* 云数据库
* [传统nosql云数据库](uniCloud/cf-database.md)
* [clientDB及JQL](uniCloud/database.md)
* [uni-clientDB组件](uniCloud/uni-clientdb-component.md)
* [云数据库入门](uniCloud/hellodb.md)
* [云函数操作云数据库](uniCloud/cf-database.md)
* [clientDB及JQL](uniCloud/clientdb.md)
* [uni-clientDB前端组件](uniCloud/uni-clientdb-component.md)
* [DB-Schema](uniCloud/schema.md)
* [openDB](https://gitee.com/dcloud/opendb)
* 云函数
......
......@@ -44,9 +44,12 @@ PC 端如下图:
#### 运行
1. 进入 admin 项目
2. 右键 cloudfuntions 运行云服务空间初始化向导(如已创建并绑定云服务空间,则跳过此步)
3. 点击工具栏的运行 -> 运行到浏览器
4. 登录页面底部进入创建管理员页面(仅允许注册一次管理员账号)
2. 在/cloudfunctions-aliyun/common/uni-id/config.json 文件中填写 `passwordSecret` 字段 (用于加密密码入库的密钥) 和 `tokenSecret` 字段 (为生成token需要的密钥)
3. 右键 cloudfuntions 运行云服务空间初始化向导(如已创建并绑定云服务空间,则跳过此步)
4. 点击工具栏的运行 -> 运行到浏览器
5. 登录页面底部进入创建管理员页面(仅允许注册一次管理员账号)
> 注意:手机端报 ``request:fail``,需要去云服务空间的``跨域配置``配置跨域域名,需带端口
### 目录结构
......@@ -77,11 +80,13 @@ PC 端如下图:
### 登录页
首次使用,可以通过登录页面底部链接创建一个超级管理员(仅允许创建一次),注册完毕后,建议从登录页面移除该链接
首次使用,可以通过登录页面底部链接创建一个超级管理员(仅允许创建一次),该接口会判断系统里如果有admin角色的用户,就不再允许添加新的超级管理员。
> 注意:注册完毕后,建议从登录页面移除该链接
![login](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c3f33850-15db-11eb-8ff1-d5dcf8779628.png)
### admin 窗体结构介绍
### 分栏窗体介绍
登录后我们会看到如下窗体, 窗体分为三个部分,topWindow 顶部窗口(导航栏),leftwindow 左侧窗口(菜单栏),右侧的内容主窗体
......@@ -150,8 +155,8 @@ export default {
menu_id: "table",
name: "表格",
url: "/pages/demo/table/table",
},
],
}
]
},
],
},
......@@ -168,7 +173,7 @@ _菜单字段解释:_
| 字段 | 类型 | 必填 | 描述 |
| :---------- | :-------- | :--- | :--------------------------------------------------- |
| menu_id | Object ID | 是 | 系统自动生成的 Id |
| menu_id | Object ID | 是 | 菜单 Id |
| name | String | 是 | 菜单文字 |
| icon | String | 否 | 菜单图标 |
| url | String | 否 | 菜单对应的页面链接(只有没有子菜单的菜单项可以配置) |
......@@ -190,7 +195,7 @@ _添加菜单记录需要注意:_
└── 手机 # 子菜单
```
1. 添加一条父菜单记录
**step 1:**添加一条父菜单记录
菜单的 `parent_id` 字段为空, 即为一级菜单
......@@ -208,7 +213,7 @@ _添加菜单记录需要注意:_
}
```
2. 添加一条子菜单记录
**step 2:**添加一条子菜单记录
将子菜单的 `parent_id` 指向父菜单的 `menu_id`即可,孙菜单就是将子菜单的 `menu_id` 当做父菜单
......@@ -247,23 +252,15 @@ $menu-text-color-actived: #409eff; /* 菜单激活前景色 */
如果想将自己开发的页面调到登录后首页,可在 page.json 调整。
### icon 图标的使用
admin 内置了一套图标以供使用,开发者也可以使用第三方图标
#### 使用内置 icon
### icon 图标
前往静态功能演示-图标菜单中,点击图标即可复制图标代码
admin 框架内置了一套icon图标,在静态功能演示-图标菜单中,点击图标即可复制图标的class定义,或者直接到`common/uni-icons.css`中查看定义,然后以如下方式使用:
> `<view class="uni-icons-gear"></view>`
或直接在标签上使用图标的 class 名称,即:
> `class='uni-icons-gear'`
#### 使用第三方 icon
```
<view class="uni-icons-gear"></view>
```
以使用 elementUI 的图标为例,在 `app.vue` 中应用图标库的样式文件:
当然,你也可以使用三方icon库。以使用 `elementUI` 的图标为例,在 `app.vue` 中导入图标库的样式文件:
```javascript
<style>
......@@ -273,27 +270,21 @@ admin 内置了一套图标以供使用,开发者也可以使用第三方图
```
在标签上使用图标的 class 名称,即:
```
<view class="el-icon-s-tools"></view>
```
> `<view class="el-icon-s-tools"></view>`
### 用户系统
> 基于 [uni-id](https://uniapp.dcloud.io/uniCloud/uni-id) 用户登录
### 权限系统
> 基于 [uni-id](https://uniapp.dcloud.io/uniCloud/uni-id?id=rbac-api) 角色权限, uni-id 是 uniCloud 之上的用户账户、权限系统
### 用户-角色-权限
- 用户表 `uni-id-users` [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=%e7%94%a8%e6%88%b7%e8%a1%a8)
uniCloud admin 框架基于 uni-id,复用 uni-id 的用户、角色、权限系统,详见[uni-id](https://uniapp.dcloud.io/uniCloud/uni-id)
- 角色表 `uni-id-roles` [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=%e8%a7%92%e8%89%b2%e8%a1%a8)
- 权限表 `uni-id-permissions` [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=%e6%9d%83%e9%99%90%e8%a1%a8)
需要注意的是,admin框架的动态菜单同样依赖uni-id的权限表(uni-id-permissions)。
- 菜单表 `opendb-admin-menus`
菜单表(opendb-admin-menus)定义如下:
| 字段 | 类型 | 必填 | 描述 |
| :--------- | :-------- | :--- | :--------------------------------------------------- |
| menu_id | Object ID | 是 | 系统自动生成的 Id |
| menu_id | Object ID | 是 | 菜单 Id |
| name | String | 是 | 菜单文字 |
| icon | String | 否 | 菜单图标 |
| url | String | 否 | 菜单对应的页面链接(只有没有子菜单的菜单项可以配置) |
......@@ -303,9 +294,6 @@ admin 内置了一套图标以供使用,开发者也可以使用第三方图
| enable | Boolean | 是 | 菜单状态:false 禁用 true 启用 |
| create_date | Timestamp | 是 | 创建时间 |
- 验证码表 `uni-verify` [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=%e7%94%a8%e6%88%b7%e8%a1%a8)
- 权限验证
admin 提供了两个内置方法,方便在页面中鉴定登录用户权限和角色:
| 方法 | 作用 | 入参 | 返回值 |
......
#### 云函数公用模块
`HBuilderX 2.6.6-alpha`起,uniCloud提供了云函数模块公用方案。以下面的目录结构为例,介绍一下如何使用。
云函数支持公共模块。多个云函数的共享部分,可以抽离为公共模块,然后被多个云函数引用。
> 版本要求:HBuilderX 2.6.6+
以下面的目录结构为例,介绍一下如何使用。
```
|--cloudfunctions
......
此差异已折叠。
......@@ -38,17 +38,34 @@ exports.main = async (event, context) => {
)传入`debugFunction: false`来实现客户端直连调用,需要注意的是此时控制台将不会打印云函数日志。
云函数中如果要使用其他服务(比如mysql数据库、redis等),可以按照nodejs的写法即可。
云函数中如果要使用其他服务(比如mysql数据库、redis等),可以按照nodejs的写法即可。但注意这些非uniCloud数据库和云函数运行环境不在一起,访问速度受影响。
**注意事项**
- 服务商为阿里云时,暂不可使用相对路径读取文件(比如`fs.readFileSync('./info.txt')`),可以使用绝对路径`fs.readFileSync(path.resolve(__dirname,'./info.txt'))`
## API列表
云函数支持nodejs和js的标准API,但除了标准API外,uniCloud扩展了一批新API,实际开发中更常用的是uniCloud的扩展API。见下:
|API |描述 |
|-- |-- |
|uniCloud.callFunction() |云函数中调用另一个云函数 [见下](uniCloud/cf-functions?id=callbyfunction) |
|uniCloud.database() |云数据库对象 [详情](uniCloud/cf-database.md) |
|uniCloud.uploadFile() |云函数上传文件到云存储 [详情](uniCloud/storage?id=uploadfile) |
|uniCloud.downloadFile() |云函数下载云存储的文件到云函数运行环境 [详情](uniCloud/storage?id=clouddownloadfile) |
|uniCloud.deleteFile() |云函数删除云存储的文件 [详情](uniCloud/storage?id=deletefile) |
|uniCloud.getTempFileURL() |获取云存储文件的临时路径 [详情](uniCloud/storage?id=gettempfileurl) |
|uniCloud.httpclient |云函数中通过http连接其他系统 [见下](uniCloud/cf-functions?id=httpclient) |
|uniCloud.logger |云函数中打印日志到uniCloud日志记录系统(非HBuilderX控制台)[详情](uniCloud/cf-logger) |
|uniCloud.sendSms() |发送短信 [详见](uniCloud/send-sms.md) |
## 访问数据库
云函数中支持访问本服务空间下的数据库,调用方式详见[规范](uniCloud/cf-database.md)
## 访问HTTP服务
## 访问HTTP服务@httpclient
`uniCloud`提供了`uniCloud.httpclient`供开发者使用。无需额外依赖,就可以请求任何 HTTP 和 HTTPS 协议的 Web 服务。`uniCloud.httpclient`返回的是一个[urllib实例](https://github.com/node-modules/urllib)
......@@ -113,13 +130,17 @@ console.log(res)
## 使用npm
在云函数中我们可以引入第三方依赖来帮助我们更快的开发。云函数的运行环境是 `Node.js`,因此我们可以使用 `npm` 安装第三方依赖。
云函数的运行环境是 `Node.js`,因此我们可以使用 `npm` 安装第三方依赖。
注意:鉴于阿里云的限制,目前仅支持全量上传云函数(整个 node_modules文件夹全部上传),因此提醒大家,精简依赖,否则可能会每次上传时间很慢,影响开发体验。
注意:鉴于阿里云的限制,目前仅支持全量上传云函数(整个 node_modules文件夹全部上传),因此提醒大家,精简依赖,否则可能会每次上传时间很慢,影响开发体验。并且太大的npm库影响云函数的运行性能。
Tips:
- 目前每个云函数上传包大小限制为10M。
## 公共模块
云函数支持公共模块。多个云函数的共享部分,可以抽离为公共模块,然后被多个云函数引用。[详见](uniCloud/cf-common)
## 客户端调用云函数
前端代码(H5前端、App、小程序),不再执行uni.request联网,而是通过`uniCloud.callFunction`调用云函数,`callFunction`定义如下:
......@@ -187,6 +208,15 @@ let callFunctionResult = await uniCloud.callFunction({
})
```
## 开发模式
实际项目中,很少会每个接口新建一个云函数。
更常见的开发模式有如下两种:
- 不写云函数,客户端直接操作数据库,开发效率更高。详见:[clientDB](uniCloud/database)
- 使用路由框架,在一个云函数内通过控制器、路由的方式编写服务器接口,控制更灵活。插件市场有很多这类插件,[详见](https://ext.dcloud.net.cn/search?q=%E8%B7%AF%E7%94%B1&orderBy=WeekDownload&cat1=7)
## 云函数配置
### 固定出口IP@eip
......@@ -327,4 +357,3 @@ exports.main = async function() {
- 使用阿里云作为服务商时,暂时无法使用相对路径读取文件,如:`fs.readFileSync('./info')`,可以替换为`fs.readFileSync(path.resolve(__dirname,'./info'))`
## 普通日志
## 开发期间打印日志
开发者在云函数内也可以使用`console.log``console.info``console.warn``console.error`四种方式打印日志。
云函数内使用`console.log``console.info``console.warn``console.error`四种方式打印日志。
HBuilderX中查看日志的教程在 [快速上手章节](/uniCloud/quickstart?id=rundebug)
## 高级日志
## 运行期记录日志,在web控制台查看
高级日志包括以下四种,以此方式输出的日志会持久化存储(有效期30天)。
系统上线后,也需要记录云函数的日志。此时不是打印在HBuilderX控制台,也不是使用`console.log`,而是使用下面的API来记录日志。
调用这些API打印的日志,会记录在uniCloud的[web控制台](https://unicloud.dcloud.net.cn)。以此方式输出的日志会持久化存储(有效期30天)。
|接口 |描述 |
|:-: |:-: |
......
......@@ -12,11 +12,12 @@
`DB Schema`中,配置数据操作的权限和字段值域校验规则,阻止前端不恰当的数据读写。详见:[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema)
如果想在数据库操作之前或之后需要在云端执行额外的动作(比如获取文章详情之后阅读量+1),`clientDB`提供了action机制。在HBuilderX项目的`cloudfunctions/uni-clientDB-actions`目录编写上传js,参考:[action](uniCloud/database?id=action)
如果想在数据库操作之前或之后需要在云端执行额外的动作(比如获取文章详情之后阅读量+1),`clientDB`提供了action云函数机制。在HBuilderX项目的`cloudfunctions/uni-clientDB-actions`目录编写上传js,参考:[action](uniCloud/database?id=action)
**注意**
- `clientDB`依赖uni-id(`1.1.10+版本`)提供用户身份和权限校验,如果你不了解uni-id,请参考[uni-id文档](https://uniapp.dcloud.net.cn/uniCloud/uni-id)
- `clientDB`依赖的uni-id需要在uni-id的config.json内添加uni-id相关配置,通过uni-id的init方法传递的参数不会对clientDB生效
- 通常在管理控制台使用`clientDB`,需要获取不同角色用户拥有的权限(在权限规则内使用auth.permission),请先查阅[uni-id 角色权限](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=rbac)
## clientDB图解
......@@ -42,7 +43,7 @@ js API可以执行所有数据库操作。`<uni-clientDB>`组件适用于查询
```js
// 获取db引用
const db = uniCloud.database()
const db = uniCloud.database() //代码块为cdb
// 使用uni-clientDB
db.collection('list')
.where({
......@@ -87,6 +88,7 @@ db.collection('list')
|SYNTAX_ERROR |语法错误 |
|PERMISSION_ERROR |权限校验未通过 |
|VALIDATION_ERROR |数据格式未通过 |
|DUPLICATE_KEY |索引冲突 |
|SYSTEM_ERROR |系统错误 |
### 前端环境变量@variable
......@@ -191,11 +193,13 @@ sql写法,对js工程师而言有学习成本,而且无法处理非关系型
需要使用skip,处理offset
这些问题竖起一堵墙,让后端开发难度加大,成为一个“专业领域”。但其实这堵墙是完全可以推倒的。
`jql`将解决这些问题,让js工程师没有难操作的数据。
具体看以下示例
这些问题竖起一堵墙,让后端开发难度加大,成为一个“专业领域”。但其实这堵墙是完全可以推倒的。
`jql`将解决这些问题,让js工程师没有难操作的数据。
具体看以下示例
```js
const db = uniCloud.database()
......@@ -326,7 +330,7 @@ order表内有以下数据,book_id字段为book表的书籍_id,quantity为
"bsonType": "object",
"required": [],
"permission": {
".read": true
"read": true
},
"properties": {
"book_id": {
......@@ -347,7 +351,7 @@ book表的db schema也要保持正确
"bsonType": "object",
"required": [],
"permission": {
".read": true
"read": true
},
"properties": {
"title": {
......@@ -404,7 +408,7 @@ db.collection('order')
```
上述查询会返回如下结果,可以看到书籍信息被嵌入到order表的book字段下,成为子节点。同时根据where条件设置,只返回书名为三国演义的订单记录。
上述查询会返回如下结果,可以看到书籍信息被嵌入到order表的book_id字段下,成为子节点。同时根据where条件设置,只返回书名为三国演义的订单记录。
```js
{
......@@ -412,14 +416,14 @@ db.collection('order')
"message": "",
"data": [{
"_id": "b8df3bd65f8f0d06018fdc250a5688bb",
"book": [{
"book_id": [{
"author": "罗贯中",
"title": "三国演义"
}],
"quantity": 555
}, {
"_id": "b8df3bd65f8f0d06018fdc2315af05ec",
"book": [{
"book_id": [{
"author": "罗贯中",
"title": "三国演义"
}],
......@@ -438,6 +442,7 @@ db.collection('order')
**注意**
- field参数字符串内没有冒号,{}为联表查询标志
- 上述示例中如果order表的`book_id`字段是数组形式存放多个book_id,也跟上述写法一致,clientDB会自动根据字段类型进行联表查询
### 查询列表分页
......@@ -446,7 +451,7 @@ db.collection('order')
1. 滚动到底加载下一页
2. 点击页码按钮切换不同页
推荐通过`<uni-clientDB>`组件处理分页,详见:[https://uniapp.dcloud.net.cn/uniCloud/uni-clientdb-component?id=page](https://uniapp.dcloud.net.cn/uniCloud/uni-clientdb-component?id=page)
推荐通过`<uni-clientDB>`组件渲染分页列表,详见:[https://uniapp.dcloud.net.cn/uniCloud/uni-clientdb-component?id=page](https://uniapp.dcloud.net.cn/uniCloud/uni-clientdb-component?id=page)
### 排序orderBy@orderby
......@@ -584,31 +589,65 @@ const db = uniCloud.database()
获取到db的表对象后,通过`add`方法新增数据记录。
`add`方法的参数为要新增的json数据,可以是单条数据、也可以是多条数据。
方法:collection.add(data)
注意:如果是非admin账户新增数据,需要在数据库中待操作表的`db schema`中要配置permission权限,赋予create为true。
**参数说明**
示例:
| 参数 | 类型 | 必填 |
| ---- | ------ | ---- |
| data | object &#124; array | 是 |
data支持一条记录,也支持多条记录一并新增到集合中。
data中不需要包括`_id`字段,数据库会自动维护该字段。
**返回值**
单条插入时
| 参数 | 类型 | 说明 |
| ---- | ------| ---------------------------------------- |
|id | String|插入记录的`_id` |
批量插入时
| 参数 | 类型 | 说明 |
| ---- | ------| ---------------------------------------- |
| inserted | Number| 插入成功条数 |
|ids | Array |批量插入所有记录的`_id` |
**示例:**
比如在user表里新增一个叫王五的记录:
```js
// 一次插入3条数据
const db = uniCloud.database();
db.collection("table1").add(
[{
name: 'Alex'
},{
name: 'Ben'
},{
name: 'John'
}]
)
db.collection('user').add({name:"王五"})
```
也可以批量插入数据并获取返回值
```js
const db = uniCloud.database();
const collection = db.collection('user');
let res = await collection.add([{
name: '张三'
},{
name: '李四'
},{
name: '王五'
}])
```
如果上述代码执行成功,则res的值将包括inserted:3,代表插入3条数据,同时在ids里返回3条记录的`_id`
如果新增记录失败,会抛出异常,以下代码示例为捕获异常:
```js
// 插入1条数据,同时判断成功失败状态
const db = uniCloud.database();
db.collection("table1")
.add({name: 'Ben'})
db.collection("user")
.add({name: '张三'})
.then((res) => {
uni.showToast({
title: '新增成功'
......@@ -626,8 +665,8 @@ db.collection("table1")
```
**Tips**
- 云服务商选择阿里云时,若集合表不存在,调用add方法会自动创建集合表
- 如果是非admin账户新增数据,需要在数据库中待操作表的`db schema`中要配置permission权限,赋予create为true。
- 云服务商选择阿里云时,若集合表不存在,调用add方法会自动创建集合表,并且不会报错。
### 删除数据记录remove
......@@ -934,17 +973,17 @@ db.auth.off('refreshToken', refreshToken)
"bsonType": "object", // 表级的类型,固定为object
"required": ['book', 'quantity'], // 新增数据时必填字段
"permission": { // 表级权限
".read": true, // 读
".create": false, // 新增
".update": false, // 更新
".delete": false, // 删除
"read": true, // 读
"create": false, // 新增
"update": false, // 更新
"delete": false, // 删除
},
"properties": { // 字段列表,注意这里是对象
"book": { // 字段名book
"bsonType": "string", // 字段类型
"permission": { // 字段权限
".read": true, // 字段读权限
".write": false, // 字段写权限
"read": true, // 字段读权限
"write": false, // 字段写权限
},
"foreignKey": "book._id" // 其他表的关联字段
},
......@@ -974,17 +1013,17 @@ db.auth.off('refreshToken', refreshToken)
"bsonType": "object", // 表级的类型,固定为object
"required": ['book', 'quantity'], // 新增数据时必填字段
"permission": { // 表级权限
".read": "doc.uid == auth.uid", // 每个用户只能读取用户自己的数据。前提是要操作的数据doc,里面有一个字段存放了uid,即uni-id的用户id。(不配置时等同于false)
".create": false, // 禁止新增数据记录(不配置时等同于false)
".update": false, // 禁止更新数据(不配置时等同于false)
".delete": false, // 禁止删除数据(不配置时等同于false)
"read": "doc.uid == auth.uid", // 每个用户只能读取用户自己的数据。前提是要操作的数据doc,里面有一个字段存放了uid,即uni-id的用户id。(不配置时等同于false)
"create": false, // 禁止新增数据记录(不配置时等同于false)
"update": false, // 禁止更新数据(不配置时等同于false)
"delete": false, // 禁止删除数据(不配置时等同于false)
},
"properties": { // 字段列表,注意这里是对象
"secret_field": { // 字段名
"bsonType": "string", // 字段类型
"permission": { // 字段权限
".read": false, // 禁止读取secret_field字段的数据
".write": false // 禁止写入(包括更新和新增)secret_field字段的数据,父级节点存在false时这里可以不配
"read": false, // 禁止读取secret_field字段的数据
"write": false // 禁止写入(包括更新和新增)secret_field字段的数据,父级节点存在false时这里可以不配
}
},
"uid":{
......@@ -1005,7 +1044,7 @@ db.auth.off('refreshToken', refreshToken)
"bsonType": "object",
"required": ['book', 'quantity'], // 新增数据时必填字段
"permission": { // 表级权限
".read": "doc.status == 'OnSell'" // 允许所有人读取状态是OnSell的数据
"read": "doc.status == 'OnSell'" // 允许所有人读取状态是OnSell的数据
},
"properties": { // 字段列表,注意这里是对象
"title": {
......@@ -1017,8 +1056,8 @@ db.auth.off('refreshToken', refreshToken)
"secret_field": { // 字段名
"bsonType": "string", // 字段类型
"permission": { // 字段权限
".read": false, // 禁止读取secret_field字段的数据
".write": false // 禁止写入(包括更新和新增)secret_field字段的数据
"read": false, // 禁止读取secret_field字段的数据
"write": false // 禁止写入(包括更新和新增)secret_field字段的数据
}
}
}
......@@ -1037,17 +1076,67 @@ db.collection('order')
.get()
```
在进行数据库操作之前,clientDB会使用permission内配置的规则对客户端操作进行一次预校验,如果预校验不通过还会通过数据库查询再进行一次校验
例:
```js
// 数据库内news表有以下数据
{
_id: "1",
user_id: "uid_1",
title: "abc"
}
```
```js
// news表对应的schema内做如下配置
{
"bsonType": "object",
"permission": { // 表级权限
"read": true,
"update": "doc.user_id == auth.uid" // 只允许修改自己的数据
},
"properties": {
"user_id": {
"bsonType": "string"
},
"title": {
"bsonType": "string"
}
}
}
```
```js
// 用户ID为uid_1的用户在客户端使用如下操作
db.collection('news').doc('1').update({
title: 'def'
})
```
此时客户端条件里面只有`doc._id == 1`,schema内又限制的`doc.user_id == auth.uid`,所以第一次预校验无法通过,会进行一次查库校验判断是否有权限进行操作。发现auth.uid确实和doc.user_id一致,上面的数据库操作允许执行。
## action@action
action的作用是在执行前端发起的数据库操作时,额外触发一段云函数逻辑。它是一个可选模块。
action的作用是在执行前端发起的数据库操作时,额外触发一段云函数逻辑。它是一个可选模块。action是运行于云函数内的,可以使用云函数内的所有接口。
当一个前端操作数据库的方式不能完全满足需求,仍然同时需要在云端再执行一些云函数时,就在前端发起数据库操作时,通过`db.action("someactionname")`方式要求云端同时执行这个叫someactionname的action。还可以在权限规则内指定某些操作必须使用指定的action,比如`"action in ['action-a','action-b']"`,来达到更灵活的权限控制。
当一个前端操作数据库的方式不能完全满足需求,仍然同时需要在云端再执行一些云函数时,就在前端发起数据库操作时,通过db.action("someactionname")方式要求云端同时执行这个叫someactionname的action。还可以在权限规则内指定某些操作必须使用指定的action,比如`"action in ['action-a','action-b']"`,来达到更灵活的权限控制。
**注意action方法是db对象的方法,只能跟在db后面,不能跟在collection()后面**
- 正确:`db.action("someactionname").collection('table1')`
- 错误:`db.collection('table1').action("someactionname")`
如果使用`<uni-clientdb>组件`,该组件也有action属性,设置action="someactionname"即可。
```html
<uni-clientdb ref="udb" collection="table1" action="someactionname" v-slot:default="{data,pagination,loading,error}">
```
action支持一次使用多个,比如使用`db.action("action-a,action-b")`,其执行流程为`action-a.before->action-b.before->执行数据库操作->action-b.after->action-a.after`。在任一before环节抛出错误直接进入after流程,在after流程内抛出的错误会被传到下一个after流程。
action是一种特殊的云函数,它不占用服务空间的云函数数量。
目前action还不支持本地运行。后续HBuilderX会支持。
目前action还不支持本地运行。后续会支持。
**新建action**
......@@ -1055,13 +1144,14 @@ action是一种特殊的云函数,它不占用服务空间的云函数数量
每个action在uni-clientDB-actions目录下存放一个以action名称命名的js文件。
在这个js文件的代码里,包括before和after两部分。
在这个js文件的代码里,包括before和after两部分,分别代表clientDB具体操作数据库前和后
- before部分的常用用途:
- before在clientDB执行前触发,before里的代码执行完毕后再开始操作数据库。before的常用用途:
* 对前端传入的数据进行二次处理
* 在此处开启数据库事务,万一操作数据库失败,可以在after里回滚
* 如果权限或字段值域校验不想配在schema和validateFunction里,也可以在这里做校验
- after部分的常用用途:
- after在clientDB执行后触发,clientDB操作数据库后触发before里的代码。after的常用用途:
* 对将要返回给前端的数据进行二次处理
* 也可以在此处处理错误,回滚数据库事务
* 对数据库进行二次操作,比如前端查询一篇文章详情后,在此处对文章的阅读数+1。因为permission里定义,一般是要禁止前端操作文章的阅读数字段的,此时就应该通过action,在云函数里对阅读数+1
......@@ -1071,7 +1161,7 @@ action是一种特殊的云函数,它不占用服务空间的云函数数量
```js
// 客户端发起请求,给todo表新增一行数据,同时指定action为add-todo
const db = uniCloud.database()
db.action('add-todo')
db.action('add-todo') //注意action方法是db的方法,只能跟在db后面,不能跟在collection()后面
.collection('todo')
.add({
title: 'todo title'
......
......@@ -151,8 +151,9 @@ uniCloud的每个云函数是一个独立进程,不存在云函数级别的多
uniCloud服务商为阿里云时支持配置全球加速,步骤如下:
1. 参考[阿里云全球加速](https://help.aliyun.com/document_detail/153198.html)文档,开通服务并对`api.bspapp.com`进行加速
2. [自行初始化uniCloud](uniCloud/init.md)传入endpoint参数,其值为开通全球加速的自有域名
1. 参考[阿里云全球加速](https://help.aliyun.com/document_detail/153198.html)文档,开通服务并对`自有域名`进行加速
2. 将上述域名CNAME到`api.bspapp.com`
3. [自行初始化uniCloud](uniCloud/init.md)传入endpoint参数,其值为开通全球加速的自有域名
### 腾讯云提示当前实名主体已经有三个账号怎么办
......
## 基础概念
`uniCloud`提供了一个 JSON 格式的文档型数据库。顾名思义,数据库中的每条记录都是一个 JSON 格式的文档。
它是nosql非关系型数据库,如果您之前熟悉sql关系型数据库,那么两者概念对应关系如下表:
|关系型 |JSON 文档型 |
|:- |:- |
|数据库 database|数据库 database |
|表 table |集合 collection |
|行 row |记录 record / doc |
|字段 column |字段 field |
|使用sql语法操作|使用MongoDB语法或jql操作 |
一个`uniCloud`服务空间,有且只有一个数据库。一个数据库支持多个集合(表)。一个集合可以有多个记录。每个记录可以有多个字段。
例如,数据库中有一个集合,名为user,存放用户信息。集合user的数据内容如下:
```json
{"name":"张三","tel":"13900000000"}
{"name":"李四","tel":"13911111111"}
```
上述数据中,每行数据表示一个用户的信息,被称之为“记录(record/doc)”。name和tel称之为“字段(field)”。而“13900000000”则是第一条记录的字段tel的值。
每个记录,都是一个完整的json文档,获取到记录后可以使用常规json方式操作。但集合并非json文档,集合是多个json文档的汇总,获取集合需要使用专门的API。
与关系型数据库的二维表格式不同,json文档数据库支持不同记录拥有不同的字段、支持多层嵌套数据。
仍然以user集合举例,要在数据库中存储每个人的每次登录时间和登录ip,则变成如下:
```json
{
"name":"张三","tel":"13900000000","login_log":[
{"login_date":1604186605445,"login_ip":"192.168.1.1"},
{"login_date":1604186694137,"login_ip":"192.168.1.2"}
]
}
{"name":"李四","tel":"13911111111"}
```
上述数据表示张三登录了2次,login_date里的值是时间戳(timestamp)格式,后续会讲解timestamp。而李四没有登录过。
可以看出json文档数据库相对于关系型数据库的灵活,李四可以没有login_log字段,也可以有这个字段但登录次数记录与张三不同。
_此处仅为举例,实际业务中,登录日志单独存放在另一个集合更好_
对于初学者,如果不了解数据库设计,可以参考[opendb](https://gitee.com/dcloud/opendb),已经预置了大量常见的数据库设计。
在uniCloud web控制台新建表时,在下面的模板中也可以选择各种`opendb`表模板,直接创建。
**字段的值,支持以下类型:**
* String:字符串
* Number:数字
* Object:对象
* Array:数组
* Bool:布尔值
* GeoPoint:地理位置点
* GeoLineStringL: 地理路径
* GeoPolygon: 地理多边形
* GeoMultiPoint: 多个地理位置点
* GeoMultiLineString: 多个地理路径
* GeoMultiPolygon: 多个地理多边形
* Date:时间
* Null:相当于一个占位符,表示一个字段存在但是值为空。
uniCloud同时支持阿里云和腾讯云,它们的数据库大体相同,有细微差异。阿里云的数据库是mongoDB4.0,腾讯云则使用自研的文档型数据库(兼容mongoDB 4.0版本)。uniCloud基本抹平了不同云厂商的差异,有差异的部分会在文档中单独标注。
如果想在云函数连接其他数据库,如mysql/redis,用法和nodejs连接这些数据库是一样的。插件市场已经有人提供了插件,见下。但注意这些用法推荐用于数据导入,主业务开发不建议这么使用。因为其他服务器上的数据库和云函数环境物理上不在一起,连接会比较慢。
- [云函数连接Mysql数据库示例](https://ext.dcloud.net.cn/plugin?id=1925)
- [云函数连接Redis数据库示例](https://ext.dcloud.net.cn/plugin?id=1846)
## 操作数据库的2种方法
云数据库支持通过云函数访问,也支持在客户端访问云数据库。
- 云函数操作数据库是较为传统的开发方式,使用nodejs写云函数、使用传统的MongoDB的API操作云数据库。
- 客户端访问云数据库,称为[clientDB](https://uniapp.dcloud.net.cn/uniCloud/clientdb)。这种开发方式可大幅提升开发效率,避免开发者开发服务器代码,并且支持更易用的`jql`语法操作数据库,是更为推荐的开发方式。[clientDB](https://uniapp.dcloud.net.cn/uniCloud/clientdb)有单独一套权限和字段值控制系统,无需单独数据库安全。(使用[clientDB](https://uniapp.dcloud.net.cn/uniCloud/clientdb)推荐HBuilderX 2.9.5以上版本。2.9.5以下的版本需单独下载插件,并且不支持`jql`,不再推荐使用。)
不管使用哪种方法,都有很多公共的概念或功能。本文档将讲述这些公共的内容。
同时左侧导航有2种方法的专项链接,描述它们各自特有的功能。
- [云函数使用传统MongoDB语法操作数据库](uniCloud/cf-database)
- [前端操作数据库,clientDB和jql](uniCloud/clientdb)
## 获取数据库对象@database
想要通过代码操作数据库,第一步要获取服务空间里的数据库对象。
不管云函数还是前端,获取数据库连接都是如下写法。前端写法需2.9.5起支持。
```js
const db = uniCloud.database(); //代码块为cdb
```
js中敲下代码块`cdb`,即可快速输入上述代码。
**DBOptions参数说明**
|字段 |类型 |必填 |描述 |平台差异说明 |
|:-: |:-: |:-: |:-: |:-: |
|spaceId|String |否 |同一账号下的,服务空间ID |仅腾讯云支持 |
```js
// 如果ID为tcb-space-demo的服务空间也在你的账号下,可以通过这种方式访问tcb-space-demo的数据库。调用此接口的服务空间和tcb-space-demo对应的服务空间均为腾讯云才可以正常使用
const db = uniCloud.database({
spaceId: 'tcb-space-demo'
});
```
## 创建一个集合/数据表@createCollection
新建的服务空间,没有一个集合。需要首先创建集合。
可以在uniCloud的web控制台([https://unicloud.dcloud.net.cn](https://unicloud.dcloud.net.cn))在web页面创建集合,也可以通过代码创建集合。
通过代码创建集合的方式,阿里云和腾讯云有差别:
- 阿里云
调用add方法,给某集合新增数据记录时,如果该集合不存在,会自动创建该集合。如下代码给table1集合新增了一条数据,如果table1不存在,会自动创建。
```js
const db = uniCloud.database();
db.collection("table1").add({name: 'Ben'})
```
- 腾讯云
腾讯云提供了专门的创建集合的API,此API仅支持云函数内运行,不支持clientDB调用。
```js
const db = uniCloud.database();
db.createCollection("table1")
```
**注意**
* 如果集合已存在,腾讯云调用createCollection方法会报错
* 腾讯云调用collection的add方法不会自动创建集合,不存在的集合会报错
* 阿里云没有createCollection方法
## 集合的3个组成部分
每个集合,其实包含3个部分:
- data:数据内容
- index:数据库索引
- schema:数据表格式定义
在uniCloud的web控制台可以看到一个集合的3部分内容。
### 数据内容
data很简单,就是存放的数据记录(record)。
实际上,创建一条新记录,是不管在web控制台创建,还是通过API创建,每条记录都会自带一个`_id`字段用以作为该记录的唯一标志。
`_id`字段是每个集合默认自带且不可删除的字段。同时,它也是集合的索引。
### 数据库索引
所谓索引,是指在集合的众多字段中挑选一个或多个字段,让数据库引擎优先处理这些字段。设置为索引的字段,在通过该字段查询记录时可以获得更快的查询速度。
一个集合可以有多个字段被设为索引。
索引分唯一型和非唯一型。
唯一型索引要求整个集合多个记录的该字段的值不能重复。比如`_id`就是唯一型索引。
假使有2个人都叫“张三”,那么他们在user集合里的区分就是依靠不同的`_id`来区分。
如果我们要根据name字段来查询,为了提升查询速度,此时可以把name字段设为非唯一索引。
还有“组合索引”的概念,可以把多个字段组合成一个“组合索引”。例如一个文章点赞记录明细表,设置文章id和用户id为组合索引,且将此组合索引设为唯一型索引,就可以限制同一用户对一篇文章多次点赞。
**在web控制台添加上述索引**
![](https://vkceyugu.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或不存在该字段的记录。
### 数据表格式定义
`DB Schema`是集合的表结构描述。描述集合有哪些字段、值域类型是什么、是否必填、数据操作权限等很多内容。
因为json文档数据库的灵活性,data数据的字段可以不在schema的描述范围内。
`DB Schema`更多是为搭配clientDB使用的,如果使用clientDB则需要详细阅读`DB Schema`的文档。
`DB Schema`涉及内容较多,另见文档:[https://uniapp.dcloud.io/uniCloud/schema](uniCloud/schema)
## 获取集合/数据表对象
创建好集合后,可以通过API获取集合对象。
```js
const db = uniCloud.database();
// 获取名为 `table1` 集合的引用
const collection = db.collection('table1');
```
**集合 Collection 的方法**
通过 `db.collection(name)` 可以获取指定集合的引用,在集合上可以进行以下操作
| 类型 | 接口 | 说明 |
| -------- | ------- | ---------------------------------------------------------------------------------- |
| 写 | add | 新增记录(触发请求) |
| 计数 | count | 获取符合条件的记录条数 |
| 读 | get | 获取集合中的记录,如果有使用 where 语句定义查询条件,则会返回匹配结果集 (触发请求) |
| 引用 | doc | 获取对该集合中指定 id 的记录的引用 |
| 查询条件 | where | 通过指定条件筛选出匹配的记录,可搭配查询指令(eq, gt, in, ...)使用 |
| | skip | 跳过指定数量的文档,常用于分页,传入 offset。clientDB组件有封装好的更易用的分页,[另见](uniCloud/uni-clientdb-component) |
| | orderBy | 排序方式 |
| | limit | 返回的结果集(文档数量)的限制,有默认值和上限值 |
| | field | 指定需要返回的字段 |
collection对象的方法可以增和查数据,删和改不能直接操作,需要collection对象通过doc或get得到指定的记录后再调用remove或update方法进行删改。
具体前端clientDB和云函数各自增删改查的方法,请单独参考文档:
- [云函数使用传统MongoDB语法操作数据库](uniCloud/cf-database)
- [前端操作数据库,clientDB和jql](uniCloud/clientdb)
## 数据导入导出和备份
uniCloud数据库提供了多种数据导入导出和备份方案。
- db\_init.json:常用于插件市场的插件做环境初始化。完整支持数据、索引、schema三部分。不适合处理大量数据,操作可能超时
- 数据库回档备份和恢复。仅腾讯云支持。支持数据和索引,不支持schema
- 数据库导入导出。仅阿里云支持,适用于大数据量操作。仅支持数据,不支持索引和schema
除上述三种方法外,开发者还可以编程处理数据的导入导出。如进行大量数据操作,建议在HBuilderX的本地运行云函数环境中操作,这样可以避免触发云端的云函数超时限制。
下面对三种方法的使用方式进行详细说明:
### `db_init.json`初始化数据库@db-init
`db_init.json`定义了一个json格式,里面包含了表名、表数据、表索引、表schema等表的所有数据。
在HBuilderX中,项目的cloudfunctions的根目录可以放置`db_init.json`文件,对文件点右键,可以按`db_init.json`的描述,在云服务空间创建相应的表、初始化表中的数据。(需HBuilderX 2.5.11+)
这个功能尤其适合插件作者,可以快速初始化插件所需的数据库环境。
**`db_init.json`的数据格式**
`db_init.json`包含三部分:数据内容(data)、数据表索引(index)、数据表结构(schema),形式如下
```json
{
"collection_test": { // 集合(表名)
"data": [ // 数据
{
"_id": "da51bd8c5e37ac14099ea43a2505a1a5", // 一般不带_id字段,防止导入时数据冲突。
"name": "tom"
}
],
"index": [{ // 索引
"IndexName": "index_a", // 索引名称
"MgoKeySchema": { // 索引规则
"MgoIndexKeys": [{
"Name": "index", // 索引字段
"Direction": "1" // 索引方向,1:ASC-升序,-1:DESC-降序,2dsphere:地理位置
}],
"MgoIsUnique": false // 索引是否唯一
}
}],
"schema": {
"bsonType": "object",
"permission": {
".read": true,
".create": false,
".update": false,
".delete": false
},
"required": [
"image_url"
],
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"image_url": {
"bsonType": "string",
"description": "可以是在线地址,也支持本地地址",
"label": "图片url"
}
}
}
}
}
```
在HBuilderX中对上述`db_init.json`点右键,可初始化数据库到云服务空间,创建`collection_test`表,并按上述json配置设置该表的index索引和schema,以及插入data下的数据。
一般opendb的表,在`db_init.json`中初始化时,不建议自定义index和schema。系统会自动从opendb规范中读取最新的index和schema。
**使用`db_init.json`导入数据库**
在HBuilderX中,对项目下的cloudfunctions目录下的`db_init.json`点右键,即可选择`初始化云数据库`。将`db_init.json`里的内容导入云端。
注意事项:
- 目前`db_init.json`为同步导入形式,无法导入大量数据,后续会实现异步导入方案。
- 如果`db_init.json`中的表名与opendb中任意表名相同,且`db_init.json`中该表名内没有编写schema和index,则在初始化时会自动拉取最新的opendb规范内对应表的schema和index。
- 如果`db_init.json`中的数据表在服务空间已存在,且`db_init.json`中该表含有schema和index,则在初始化时schema会被替换,新增索引会被添加,已存在索引不受影响。
**生成`db_init.json`的方式**
在uniCloud web控制台的数据库界面,左侧导航点击 生成`db_init.json`,会将选择的表的内容、索引、表结构导出为`db_init.json`文件。
注意事项:
- 如果表名与opendb中任意表名相同,web控制台导出时将不会带上schema和index。
- web控制台导出时默认不包括`_id`字段,在导入时,数据库插入新记录时会自动补`_id`字段。如果需要指定`_id`,需要手工补足数据。
### 数据库回档备份和恢复@backup
**此功能暂时只有腾讯云支持**
uniCloud腾讯云版会在每天自动备份一次数据库,最多保留7天。这让开发者不再担心数据丢失。
**操作说明**
1. 登录[uniCloud后台](https://unicloud-dev.dcloud.net.cn/)
2. 点击左侧菜单`云数据库 --> 数据库回档`,点击`新建回档`
3. 选择可回档时间
4. 选择需要回档的集合(注意:回档后集合不能与现有集合重名,如需对集合重命名可以在集合列表处操作)
![数据库回档](https://img.cdn.aliyun.dcloud.net.cn/uni-app/uniCloud/unicloud-db-backup.jpg)
### 数据导出为文件@export
**此功能暂时只有阿里云支持**
此功能主要用于导出整个集合的数据
**用法**
1. 进入[uniCloud web控制台](https://unicloud.dcloud.net.cn/home),选择服务空间,或者直接在HBuilderX云函数目录`cloudfunctions`上右键打开uniCloud web控制台
2. 进入云数据库选择希望导入数据的集合
3. 点击导出按钮
4. 选择导出格式,如果选择csv格式还需要选择导出字段
5. 点击确定按钮等待下载开始即可
**注意**
- 导出的json文件并非一般情况下的json,而是每行一条json数据的文本文件
- 导出为csv时必须填写字段选项。字段之间使用英文逗号隔开。例如:`_id, name, age, gender`
- 数据量较大时可能需要等待一段时间才可以开始下载
### 从文件导入数据@import
**此功能暂时只有阿里云支持**
uniCloud提供的`db_init.json`主要是为了对数据库进行初始化,并不适合导入大量数据。与`db_init.json`不同,数据导入功能可以导入大量数据,目前支持导入 CSV、JSON 格式(关于json格式看下面注意事项)的文件数据。
**用法**
1. 进入[uniCloud web控制台](https://unicloud.dcloud.net.cn/home),选择服务空间,或者直接在HBuilderX云函数目录`cloudfunctions`上右键打开uniCloud web控制台
2. 进入云数据库选择希望导入数据的集合
3. 点击导入,选择json文件或csv文件
4. 选择处理冲突模式(关于处理冲突模式请看下方注意事项)
5. 点击确定按钮等待导入完成即可
**注意**
- 目前导入文件最大限制为50MB
- 导入导出文件无法保留索引和schema
- 导入导出csv时数据类型会丢失,即所有字段均会作为字符串导入
- 冲突处理模式为设定记录_id冲突时的处理方式,`insert`表示冲突时依旧导入记录但是是新插入一条,`upsert`表示冲突时更新已存在的记录
- 这里说的json文件并不是标准的json格式,而是形如下面这样每行一个json格式的数据库记录的文件
```json
{"a":1}
{"a":2}
```
......@@ -87,11 +87,11 @@ exports.main = async (event, context) => {
在云函数对应的目录右键可以配置运行测试参数,如下图,选择之后会生成一个形如`${函数名}.param.json`的文件,此文件内容会在云函数`上传并运行`时作为参数传入云函数内。详细用法可参考:[配置运行测试参数](https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=runparam)
## 本地运行云函数注意事项@runlocal
## 本地运行云函数@runlocal
自2.8.1版本起HBuilderX支持云函数本地运行,调试云函数更加方便快捷。此外还可以方便批量导入数据及文件,不再受云函数超时限制。
**目前只支持本地运行,debug断点还在开发中**
**目前只支持本地运行打日志。断点debug还在开发中**
#### 使用方式
......@@ -102,7 +102,7 @@ exports.main = async (event, context) => {
![](https://img.cdn.aliyun.dcloud.net.cn/uni-app/uniCloud/uniCloud-local-1.jpg)
#### 注意事项
#### 本地运行注意事项
**使用公用模块**
......@@ -131,6 +131,8 @@ const hour = getOffsetDate(8).getHours()
// 获取时间戳无需使用此方式utc+0时间戳是与utc+8时间戳一致的
```
推荐使用`<uni-dateformat>`组件格式化显示日期,[详情](https://ext.dcloud.net.cn/plugin?id=3279)
**数据与存储**
请务必注意云函数在本地运行时依然是连接的云端数据库与存储
......@@ -141,7 +143,7 @@ const hour = getOffsetDate(8).getHours()
服务空间所使用的nodejs版本为8.9,本地运行时使用的本地nodejs可能与服务空间的nodejs版本并不一致,在本地测试之后部署到云端也务必测试一下兼容性。
**日志打印**
**控制台日志打印**
目前本地运行云函数只能打印字符串类型的值,其他类型请注意转换为字符串
......@@ -231,6 +233,11 @@ App端真机调试输出云函数日志,如下图所示:
uniCloud的[web控制台](https://unicloud.dcloud.net.cn/)可以查看线上云函数的所有运行日志,而不仅仅是开发时的运行日志。
## clientDB - 前端直接操作数据库
uniCloud支持云函数,但其实大多数场景下并不需要写云函数,可以通过clientDB直接操作云数据库。
文档另见:[clientDB](https://uniapp.dcloud.io/uniCloud/database)
## 小程序中使用uniCloud的白名单配置
......@@ -284,15 +291,10 @@ H5前端js访问云函数,涉及跨域问题,导致前端js无法连接云
**H5前端页面部署问题**
uniCloud支持前端页面部署,在HBuilderX中点发行菜单,生成H5,将生成的前端文件部署在uniCloud的前端网页托管内即可[详情参考](uniCloud/hosting.md)
uniCloud支持前端页面部署,在HBuilderX中点发行菜单,生成H5,将生成的前端文件部署在uniCloud的前端网页托管内即可[详情参考](uniCloud/hosting.md)
需要注意的是你仍在[uniCloud web控制台](https://unicloud.dcloud.net.cn) 配置H5安全域名。
**m3w.cn二级域名申请**
若为新冠抗疫需紧急上线H5,来不及注册域名,可申请使用DCloud提供的m3w.cn的二级域名,示例:[hellounicloud.m3w.cn](https://hellounicloud.m3w.cn) 。此时请使用你注册DCloud账户的邮箱向service@dcloud.io发邮件申请,提供你的appid、计划使用的二级域名名称、解析的ip地址、应用的使用用途。
如果不发布H5,则不需要自己申请或准备域名。App和小程序里直接调用云函数即可,无需域名。
**Tips**
......
# uniCloud 更新日志
======================================
#### 2020-11-13
+ 阿里云支持事务(startTransaction方式,暂不支持ranTransaction)[详情](https://uniapp.dcloud.net.cn/uniCloud/cf-database?id=starttransaction)
#### 2020-10-24
+ clientDB 去除schema内permission中的点,例:`.write`改为`write`,旧写法仍然支持。
+ clientDB 优化无权限操作时的报错提示
#### 2020-10-24
+ 【重要】新增 clientDB 支持 `jql` 查询语法,大幅降低数据库操作难度 [详情](https://uniapp.dcloud.net.cn/uniCloud/database?id=jsquery)、大幅简化联表查询 [详情](https://uniapp.dcloud.net.cn/uniCloud/database?id=lookup)
+ 【重要】新增 uni-clientDB 组件,在前端通过组件直接获得云数据库内容,并直接绑定到界面上,大幅提升开发效率 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-clientdb-component)
+ 【重要】调整 clientDB内置,云端不再需要单独的clientDB云函数,前端无需引用clientDB的js sdk,直接在前端写`const db = uniCloud.database()`即可 [详情](https://uniapp.dcloud.net.cn/uniCloud/database)
+ 【重要】调整 uni-clientDB-actions 目录调整到 cloudfunctions 根目录 [详情](https://uniapp.dcloud.net.cn/uniCloud/database?id=action)
+ 【重要】调整 clientDB云函数的permission和validator子目录废除,只需在 DB Schema 中书写permission和validator内容,保存即可直接生效,无需再次导出
+ 【重要】新增 `uniCloud Admin 基础框架`(HBuilderX新建项目可选择该模板) [详情](https://uniapp.dcloud.net.cn/uniCloud/admin)
+ 【重要】新增 web控制台 云数据库配置 DB Schema 后,可直接生成前端工程,含数据表单新增、修改页面,以及校验规则。大幅提升开发效率
+ 【重要】腾讯云 正式商用 [详见](https://uniapp.dcloud.net.cn/uniCloud/price)
+ 新增 web控制台 云数据库支持导出db_init.json
+ 新增 web控制台 服务空间改名
+ 新增 web控制台 云数据库支持`扩展校验函数`,可自主编程实现更复杂的数据校验逻辑,同时在 DB Schema 中引用这些`扩展校验函数`
+ 修复 阿里云 数据库set方法表现不正确的Bug
+ uni-id 新增 开发者callFunction时可自行传入uniIdToken,此时不再从storage获取token
#### 2020-10-13
+ 腾讯云 全面开放企业用户按量计费服务空间的购买 [详情](https://uniapp.dcloud.net.cn/uniCloud/price?id=price-info)
......
此差异已折叠。
**重要:** clientDB重大升级,在HBuilderX 2.9.5+中已经内置,不再需要单独下载插件。并且新版增加大量功能。本文已过期,推荐使用clientDB的开发者升级到HBuilderX 2.9.5+,并阅读新文档:[https://uniapp.dcloud.net.cn/uniCloud/database](https://uniapp.dcloud.net.cn/uniCloud/database)
**重要:** clientDB重大升级,在HBuilderX 2.9.5+中已经内置,不再需要单独下载插件。并且新版增加大量功能。本文已过期,推荐使用clientDB的开发者升级到HBuilderX 2.9.5+,并阅读新文档:[https://uniapp.dcloud.net.cn/uniCloud/clientdb](https://uniapp.dcloud.net.cn/uniCloud/clientdb)
## 旧版clientDB简介
......
......@@ -8,7 +8,7 @@
有了`<uni-clientdb>` 组件,**上述工作只需要1行代码**!写组件,设组件的属性,在属性中指定要查什么表、哪些字段、以及查询条件,就OK了!
如下
敲下`udb`代码块,得到如下代码
```html
<uni-clientdb v-slot:default="{data, loading, error, options}" collection="table1" field="field1" :getone="true" where="id=='1'">
......@@ -22,7 +22,7 @@
`<uni-clientdb>` 组件的查询语法是`jql`,这是一种比sql语句和nosql语法更简洁、更符合js开发者习惯的查询语法。没学过sql或nosql的前端,也可以轻松掌握。[jql详见](https://uniapp.dcloud.net.cn/uniCloud/uni-clientDB?id=jsquery)
`<uni-clientdb>` 组件只支持查询。如果要对数据库进行新增修改删除操作,仍需使用clientDB的js API进行add、update、remove操作。
`<uni-clientdb>` 组件只支持查询。如果要对数据库进行新增修改删除操作,仍需使用clientDB的js API进行add、update、remove操作。另,`<uni-clientdb>` 组件自带了一个封装remove方法,见下文方法章节
`<uni-clientdb>` 组件没有预置到基础库,需单独下载插件到工程中。下载地址为:[https://ext.dcloud.net.cn/plugin?id=3256](https://ext.dcloud.net.cn/plugin?id=3256)
......@@ -47,7 +47,7 @@
|page-data|String|分页策略选择。值为 `add` 代表下一页的数据追加到之前的数据中,常用于滚动到底加载下一页;值为 `replace` 时则替换当前data数据,常用于PC式交互,列表底部有页码分页按钮|
|page-current|Number|当前页|
|page-size|Number|每页数据数量|
|getcount|Boolan|是否查询总数据条数,默认 `false`,需要分页模式时指定为 `true`|
|getcount|Boolean|是否查询总数据条数,默认 `false`,需要分页模式时指定为 `true`|
|getone|Boolean|指定查询结果是否仅返回数组第一条数据,默认 false。在false情况下返回的是数组,即便只有一条结果,也需要[0]的方式获取。在值为 true 时,直接返回结果数据,少一层数组。一般用于非列表页,比如详情页|
|action|string|云端执行数据库查询的前或后,触发某个action函数操作,进行预处理或后处理,[详情](https://uniapp.dcloud.net.cn/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值|
......@@ -56,6 +56,8 @@
TODO:暂不支持groupby、in子查询功能。后续会补充
注意:`page-current/page-size` 改变不重置数据(`page-data="replace"`)除外,`collection/action/field/getcount/orderby/where` 改变后清空已有数据
**示例**
......@@ -141,7 +143,7 @@ handleError(e) {
## 方法
- loadData
### loadData
当 `<uni-clientdb>` 组件的 manual 属性设为为 true 时,不会在页面初始化时联网查询数据,此时需要通过本方法手动加载数据
......@@ -149,7 +151,7 @@ handleError(e) {
this.$refs.udb.loadData() //udb为uni-clientdb组件的ref属性值
```
- loadMore
### loadMore
在列表的加载下一页场景下,使用ref方式访问组件方法,加载更多数据,每加载成功一次,当前页 +1
......@@ -157,7 +159,78 @@ this.$refs.udb.loadData() //udb为uni-clientdb组件的ref属性值
this.$refs.udb.loadMore() //udb为uni-clientdb组件的ref属性值
```
- dataList
### remove
在列表页面,如果想删除一个item,原本要做很多事:
1. 弹出删除确认框
2. 弹出loading
3. 调用clientDB的js api删除云端数据
4. 接收云端删除结果,如果成功则关闭loading
5. 进一步删除列表的data中对应的item,刷新页面
为减少重复开发,`clientDB`组件提供了remove方法,在列表渲染时绑定好index,直接调用remove方法即可一行代码完成上述5步。
首先在列表生成的时候给删除按钮绑定好id:
```html
<uni-clientdb ref="udb" :collection="collectionName" v-slot:default="{data,pagination,loading,error}">
<uni-table :loading="loading" :emptyText="error.message || '没有更多数据'" border stripe >
<uni-tr>
<uni-th>用户名</uni-th>
<uni-th>操作</uni-th>
</uni-tr>
<uni-tr v-for="(item,index) in data" :key="index">
<uni-th>{{item.username}}</uni-th>
<uni-td>
<view>
<button @click="confirmDelete(item._id)" type="warn">删除</button>
</view>
</uni-td>
</uni-tr>
</uni-table>
</uni-clientdb>
```
然后confirmDelete方法里面只有一行代码:
```js
confirmDelete(id) {
this.$refs.udb.remove(id)
}
```
`clientDB`组件的remove方法的参数只支持传入数据库的_id进行删除,不支持其他where条件删除。
参数传入的_id支持单个,也支持多个,即可以批量删除。多个id的格式是:
```js
this.$refs.udb.remove(["5f921826cf447a000151b16d", "5f9dee1ff10d2400016f01a4"])
```
在uniCloud的web控制台的`DB Schema`界面,可自助生成数据表的admin管理插件,其中有多行数据批选批删示例。
完整实例,第二个是可选参数
```js
var ids = ["5f921826cf447a000151b16d", "5f9dee1ff10d2400016f01a4"]
this.$refs.udb.remove(ids, {
action: '', // 删除前后的动作
confirmTitle: '提示', // 确认框标题
confirmContent: '是否删除该数据', // 确认框内容
callback: (res) => { // 删除成功后的回调
const { code, message } = res
}
})
```
注意:
- 如果列表分页采取分页组件,即page-data值为`replace`,每页有固定数量,那么`clientDB`组件的remove方法删除数据后,会重新请求当前页面数据。
- 如果列表采取滚动加载方式,即page-data值为`add`,滚动加载下一页数据,那么`clientDB`组件的remove方法删除数据后,不会重新请求数据,而是从已有数据移除已删除项。(组件版本1.1.0+支持)
### dataList
在js中,可以打印`<uni-clientdb>` 组件的data
......@@ -189,7 +262,7 @@ H5平台,开发模式下浏览器控制台输入 `unidev.clientDB.data`,可
</template>
```
联表查询详情参考 [https://uniapp.dcloud.net.cn/uniCloud/database?id=lookup](https://uniapp.dcloud.net.cn/uniCloud/database?id=lookup)
联表查询详情参考 [https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=lookup](https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=lookup)
## 列表分页@page
- 列表分页模式1:上拉加载上一页。下一页的查询结果会追加合并到data里
......@@ -298,7 +371,7 @@ H5平台,开发模式下浏览器控制台输入 `unidev.clientDB.data`,可
</view>
<view class="loading" v-if="loading">加载中...</view>
<!-- 分页组件 -->
<uni-pagination show-icon :page-size="pagination.size" total="pagination.total" @change="onpagination" />
<uni-pagination show-icon :page-size="pagination.size" total="pagination.count" @change="onpagination" />
</uni-clientdb>
</view>
</template>
......
......@@ -8,13 +8,19 @@
`uni-id``uniCloud`开发者提供了简单、统一、可扩展的用户管理能力封装。
[clientDB](uniCloud/clientDB)[DB Schema](uniCloud/schema)[uniCloud admin](uniCloud/admin),这些产品都基于`uni-id`的账户体系。可以说`uni-id`是uniCloud不可或缺的基础能力。
# 组成部分
`uni-id`包括如下组成部分:
1. 云数据库
主表为 `uni-id-users` 表,保存用户的基本信息。
主表为 `uni-id-users` 表,保存用户的基本信息。扩展字段有很多,如实名认证数据、工作履历数据,开发者可以自由扩展。
还有 uni-id- 开头的十几个附表,比如权限表`uni-id-permissions`、角色表`uni-id-roles`、积分表`uni-id-scores`、设备表`uni-id-device`...
扩展字段有很多,如实名认证数据、工作履历数据,开发者可以自由扩展
所有`uni-id`的数据表,在uniCloud web控制台新建表的界面上,都可以选择这些数据表模板,直接建好
2. 云函数
......@@ -29,6 +35,7 @@
uniCloud框架底层,会自动在callfunction时传递`uni-id`的token(uni-app 2.7.13+版本)。在云函数的event中可直接拿到`uni-id`的token。也就是说开发者无需自己管理token了。
# uni-id 对开发者的价值
1. 节省了大量重复劳动
2. 降低门槛,前端开发者无需纠结怎样设计数据库设计才更合理
3. 多系统打通用户和上下游协同
......@@ -39,18 +46,21 @@ uniCloud框架底层,会自动在callfunction时传递`uni-id`的token(uni-a
在插件市场,每类模板插件都能找到,但他们如果不是基于同一套用户体系设计,就很难整合。
DCloud推荐所有uniCloud的应用,都基于`uni-id`来做。
所有uniCloud的应用,几乎都基于`uni-id`来做。
有了统一的账户规范,并且围绕这套账户规范,有各种各样插件,那么开发者可以随意整合这些插件,让数据连同。
规范,还可以让上下游充分协同。插件市场会出现各种数据迁移插件,比如把从discuz里把用户迁移到`uni-id`中的插件,相信围绕这套规范的产业链会非常活跃。
事实上,[clientDB](uniCloud/clientDB)[DB Schema](uniCloud/schema)[uniCloud admin](uniCloud/admin)等重要uniCloud产品,以及插件市场上各种优秀的轮子,都是基于`uni-id`的。
# 现状和未来
`uni-id`已完的内容:
`uni-id`已完的内容:
- 注册、登录、发送短信验证码、密码加密保存、修改密码、token管理(短信验证码功能需要HBuilderX 2.8.3+)
- 三方登录:App中的微信登录、微信小程序中的微信登录、支付宝小程序中的支付宝账户登录
- rbac权限角色体系
关于还缺少的部分,哪些DCloud在完善,哪些希望开发者给共同完善开源项目,计划与边界公布如下:
......@@ -66,10 +76,6 @@ DCloud暂无计划开发百度、头条、QQ等小程序的登录,以及Apple
目前插件市场里已经有不少相关插件,未来DCloud会整合到`uni-id`中。
4. 权限管理ACL
这部分欢迎开发者参与完善。
其他方面,各种常见开源项目如discuz、wordPress、ecshop的用户导入插件,不属于`uni-id`主工程,欢迎开发者单独提交插件到插件市场。
`uni-id`的git仓库:[https://gitee.com/dcloud/uni-id.git](https://gitee.com/dcloud/uni-id.git)
......@@ -79,17 +85,15 @@ DCloud暂无计划开发百度、头条、QQ等小程序的登录,以及Apple
使用uni-id需要按照以下步骤操作
1. 准备2.7.14或以上版本的HBuilderX
1. 准备2.8或以上版本的HBuilderX
2. 插件市场导入`uni-id`公用模块,[插件市场 uni-id](https://ext.dcloud.net.cn/plugin?id=2116)
3. 修改公用模块`uni-id`下的`config.json`内所需参数(请参考下面config.json的说明)
4. 上传`cloudfunctions/common`下的`uni-id`模块
5. 按照[公用模块使用说明](https://uniapp.dcloud.io/uniCloud/cf-common)在云函数下安装`uni-id`模块
6. 创建`uni-id-users``uni-verify`集合(可以直接使用示例项目里面的db_init.json进行初始化
6. 创建`uni-id-users``uni-verify`集合(uni-verify是验证码表。可以使用示例项目里面的db_init.json进行初始化、也可以在web控制台新建表时选择这些表模块
或者直接导入[uni-id在插件市场的示例工程](https://ext.dcloud.net.cn/plugin?id=2116)
导入示例项目时,如果选择腾讯云,在HBuilderX2.7及以下版本中,需要进入项目目录,手动将目录`cloudfunctions-aliyun`改名为`cloudfunctions-tcb`,然后在HBuilderX中右键cloudfunctions绑定服务空间。
**config.json的说明**
注意:
......@@ -109,6 +113,8 @@ DCloud暂无计划开发百度、头条、QQ等小程序的登录,以及Apple
+ 另外可以按照客户端平台进行不同的配置,参考下面示例
**下面的配置文件中所有时间的单位都是秒**
> !!!重要!!! passwordSecret与tokenSecret十分重要,切记妥善保存。修改passwordSecret会导致老用户使用密码无法登陆,修改tokenSecret会导致所有已经下发的token失效。如果重新导入uni-id切勿直接覆盖config.json相关配置
```json
// 如果拷贝此内容切记去除注释
......@@ -168,7 +174,7 @@ DCloud暂无计划开发百度、头条、QQ等小程序的登录,以及Apple
为什么需要权限管理?
- 对于后台管理系统,除了超级管理员,不同账号通常需根据职位、责任设定不同的系统权限。
- [clientDB](https://uniapp.dcloud.net.cn/uniCloud/uni-clientDB)允许前端直接操作数据库,但部分字段应该是系统计算或管理员设置的,比如文章的阅读数、收藏数及是否加精置顶,这些字段不允许普通用户在前端通过clientDB直接修改,此时也需要通过权限控制来保证系统的安全稳定。
- [clientDB](https://uniapp.dcloud.io/uniCloud/database)允许前端直接操作数据库,但部分字段应该是系统计算或管理员设置的,比如文章的阅读数、收藏数及是否加精置顶,这些字段不允许普通用户在前端通过clientDB直接修改,此时也需要通过权限控制来保证系统的安全稳定。
`uni-id`如何解决权限管理问题?
- 基于经典的RBAC模型实现内置角色权限系统。
......@@ -198,7 +204,7 @@ RBAC:Role-Based Access Control,基于角色的访问控制。
"_id":"5f8428181c229600010389f6",
"username":"uniapp",
"email":"hr2013@dcloud.io",
role:[
"role":[
"USER_ADMIN",
"NOTICE_ADMIN"
],
......@@ -234,7 +240,7 @@ RBAC:Role-Based Access Control,基于角色的访问控制。
"_id":"5f8428181c229600010389f6",
"role_id":"USER_ADMIN",
"role_name":"人事管理",
permission:[
"permission":[
"USER_ADD",
"USER_EDIT",
"USER_DEL"
......@@ -245,7 +251,7 @@ RBAC:Role-Based Access Control,基于角色的访问控制。
"_id":"5f842836d8daea0001906785",
"role_id":"NOTICE_ADMIN",
"role_name":"公告管理",
permission:[
"permission":[
"NOTICE_ADD",
"NOTICE_EDIT",
"NOTICE_DEL"
......@@ -261,7 +267,7 @@ RBAC:Role-Based Access Control,基于角色的访问控制。
// db-permission/uni-id-users.js
{
".update":"doc._id == auth.uid || 'USER_ADMIN' in auth.role" //用户自己或人事管理员可执行用户表的.update操作
"update":"doc._id == auth.uid || 'USER_ADMIN' in auth.role" //用户自己或人事管理员可执行用户表的.update操作
}
```
......@@ -308,7 +314,7 @@ RBAC:Role-Based Access Control,基于角色的访问控制。
// db-permission/uni-id-users.js
{
".update":"doc._id == auth.uid || 'USER_EDIT' in auth.permission" //用户自己或有`USER_EDIT`权限的用户,可执行用户表的.update操作
"update":"doc._id == auth.uid || 'USER_EDIT' in auth.permission" //用户自己或有`USER_EDIT`权限的用户,可执行用户表的.update操作
}
```
......@@ -380,7 +386,7 @@ username可以是字符串、可以是email、可以是手机号,本插件不
比如要求username为手机号,则自行在前端界面上做好提示,在后台对格式进行校验。
password入库时会自动进行一次sha1加密,不明文存储密码。
password入库时会自动进行一次sha1加密,不明文存储密码。秘钥是开发者在config.json里自行配置的。
**响应参数**
......@@ -452,6 +458,7 @@ uniCloud.callFunction({
**注意**
- 登录成功之后会返回token,在获取token之后应进行持久化存储,键值为:uniIdToken,`uni.setStorageSync('uniIdToken',res.result.token)`
- 登录时请注意自行验证数据有效性
**user参数说明**
......@@ -460,7 +467,7 @@ uniCloud.callFunction({
| username | String| 是 |用户名 |
| password | String| 是 |密码 |
| needPermission| Boolean | 否 |设置为true时会在checkToken时返回用户权限(permission),建议在管理控制台中使用 |
| queryField | Array| 否 |指定从哪些字段中比对username,不填默认与数据库内的username字段对比, 可取值'username'、'email'、'mobile'|
| queryField | Array| 否 |指定从哪些字段中比对username(传入参数均为username),不填默认与数据库内的username字段对比, 可取值'username'、'email'、'mobile'|
**响应参数**
......@@ -605,6 +612,8 @@ exports.main = async function(event,context) {
| code | Number| 是 |错误码,0表示成功 |
| message | String| 是 |详细信息 |
**注意:修改密码会导致所有token失效**
**示例代码**
```js
......@@ -651,6 +660,8 @@ exports.main = async function(event,context) {
| code | Number| 是 |错误码,0表示成功 |
| message | String| 是 |详细信息 |
**注意:重置密码会导致所有token失效**
**示例代码**
```js
......@@ -1378,10 +1389,10 @@ export default {
}).then((res) => {
uni.showModal({
showCancel: false,
content: JSON.stringify(e.result)
content: JSON.stringify(res.result)
})
if (res.result.code === 0) {
uni.setStorageSync('uniIdToken', e.result.token)
uni.setStorageSync('uniIdToken', res.result.token)
}
}).catch(() => {
uni.showModal({
......@@ -1556,7 +1567,7 @@ exports.main = async function(event,context) {
| 字段 | 类型 | 必填| 说明 |
| --- | --- | --- | --- |
| code | String| 是 |微信登录返回的code |
| code | String| 是 |支付宝登录返回的code |
|platform |String |否 |客户端类型:`mp-weixin``app-plus`,默认uni-id会自动取客户端类型,但是在云函数url化等场景无法取到客户端类型,可以使用此参数指定 |
**响应参数**
......@@ -2087,15 +2098,15 @@ exports.main = async function(event,context) {
| 字段 | 类型 | 必填| 描述 |
| ----------------| --------- | ----| ------------------------------------------- |
| \_id | Object ID | 是 | 存储文档 ID(用户 ID),系统自动生成 |
| username | String | | 用户名,不允许重复 |
| username | String | | 用户名,不允许重复 |
| password | String | 否 | 密码,加密存储 |
| nickname | String | 否 | 用户昵称 |
| gender | Integer | 否 | 用户性别:0 未知 1 男性 2 女性 |
| status | Integer | 是 | 用户状态:0 正常 1 禁用 2 审核中 3 审核拒绝 |
| mobile | String | 否 | 手机号码 |
| mobile_confirmed| Integer | 否 | 手机号验证状态:0 未验证 1 已验证 |
| mobile_confirmed| Integer | 否 | 手机号验证状态:0 未验证 1 已验证,未验证用户不可登录 |
| email | String | 否 | 邮箱地址 |
| email_confirmed | Integer | 否 | 邮箱验证状态:0 未验证 1 已验证 |
| email_confirmed | Integer | 否 | 邮箱验证状态:0 未验证 1 已验证,未验证用户不可登录 |
| avatar | String | 否 | 头像地址 |
| wx_unionid | String | 否 | 微信unionid |
| wx_openid | Object | 否 | 微信各个平台openid |
......@@ -2203,6 +2214,19 @@ exports.main = async function(event,context) {
| comment | String | 否 | 备注 |
| created_date | Timestamp | 是 | 权限创建时间 |
## 更多表
还有更多uni-id的配套数据表,可以在uniCloud web控制台新建表时选择相应模板。此处不再详述,仅罗列清单:
- 积分表:uni-id-scores
- 地址信息表:uni-id-address
- 订单表:uni-id-base-order
- 设备表:uni-id-device
- 关注粉丝表:uni-id-followers
- 日志表:uni-id-log
- 任务表:uni-id-task
- 任务日志表:uni-id-task-log
# 错误码
`1.1.0`版本使用此错误码规范
......
## 一键登录@univerify
univerify 是DCloud 推出的一键登录产品,通过与运营商深度合作,实现APP用户无需输入帐号密码,即可使用本机手机号码自动登录的能力。
univerify是替代短信验证登录的下一代登录验证方式,能消除现有短信验证模式等待时间长、操作繁琐和容易泄露的痛点。
## 客户端@client
客户端如何使用一键登录请参考此文档:[univerify 使用指南](https://ask.dcloud.net.cn/article/38009)
## 云函数@cloud
客户端调用一键登录接口会获取如下结果
```js
{
"target": {
"id": "univerify",
"description": "一键登录",
"authResult": {
"openid": "xxx",
"access_token": "xxx"
}
}
}
```
使用上面结果中的`openid``access_token`即可在`云函数`内调用接口获取手机号
**相关文档**
- [uniCloud快速上手](https://uniapp.dcloud.net.cn/uniCloud/quickstart)
- [云函数URL化](https://uniapp.dcloud.net.cn/uniCloud/http)
**uni-app项目**
如果开发uni-app项目可以使用callFunction的方式调用云函数
```js
// 客户端
uniCloud.callFunction({
name: 'xxx', // 你的云函数名称
data: {
accessToken: 'xxx', // 客户端一键登录接口返回的accessToken
openid: 'xxx' // 客户端一键登录接口返回的openid
}
}).then(res => {
// res.result = {
// code: '',
// message: '',
// phoneNumber: '138xxxxxxx'
// }
}).catch(err=>{
// 处理错误
})
// 云函数
module.exports = async(event){
const res = await uniCloud.getPhoneNumber({
provider: 'univerify',
apiKey: 'xxx', // 在开发者中心开通服务并获取apiKey
apiSecret: 'xxx', // 在开发者中心开通服务并获取apiSecret
accessToken: event.accessToken,
openid: event.openid
})
return res
}
```
**5+项目**
5+项目不可使用callFunction请求云函数,这时候可以使用云函数URL化让5+项目通过http请求的方式访问云函数
```js
// 客户端
const xhr = new plus.net.XMLHttpRequest();
xhr.onload = function(e) {
const {
code,
message,
phoneNumer // 取得手机号
} = JSON.parse(xhr.responseText)
}
xhr.open( "POST", "https://xxx" ); // url应为云函数Url化之后的地址,可以在uniCloud web控制台云函数详情页面看到
xhr.setRequestHeader('Content-Type','application/json');
xhr.send(JSON.stringify({
accessToken: 'xxx', // 客户端一键登录接口返回的accessToken
openid: 'xxx' // 客户端一键登录接口返回的openid
}));
// 云函数,下面仅展示客户端使用post方式发送content-type为application/json请求的场景
module.exports = async(event){
let body = event.body
if(event.isBase64Encoded) {
body = Buffer.from(body,'base64')
}
const {
accessToken,
openid
} = JSON.parse(body)
const res = await uniCloud.getPhoneNumber({
provider: 'univerify',
appid: 'xxx', // DCloud appid,不同于callFunction方式调用,使用云函数Url化需要传递DCloud appid参数
apiKey: 'xxx', // 在开发者中心开通服务并获取apiKey
apiSecret: 'xxx', // 在开发者中心开通服务并获取apiSecret
accessToken: accessToken,
openid: openid
})
return res
}
```
\ No newline at end of file
......@@ -12,5 +12,5 @@
"message": "chore(release): publish %s"
}
},
"version": "2.0.0-29320201014001"
"version": "2.0.0-alpha-29920201113004"
}
{
"name": "@dcloudio/uni-app-plus-nvue",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app app-plus-nvue",
"main": "dist/index.js",
"repository": {
......
此差异已折叠。
{
"name": "@dcloudio/uni-app-plus",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app app-plus",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-automator",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app automator",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-cli-shared",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-cli-shared",
"main": "lib/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-h5-ui",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app h5 ui",
"main": "dist/index.umd.min.js",
"repository": {
......
此差异已折叠。
......@@ -245,6 +245,22 @@
"/core/helpers/protocol/location/choose-location.js",
"chooseLocation"
],
[
"/platforms/h5/view/components/map/index.vue",
"Map"
],
[
"/core/view/components/input/index.vue",
"Input"
],
[
"/core/view/components/scroll-view/index.vue",
"ScrollView"
],
[
"/platforms/h5/service/api/location/get-location.js",
"getLocation"
],
[
"/platforms/h5/components/system-routes/choose-location/index.vue",
"ChooseLocation"
......@@ -286,6 +302,15 @@
]
]
],
"chooseFile": [
"/platforms/h5/service/api/media/choose-file.js",
[
[
"/core/helpers/protocol/media/choose-file.js",
"chooseFile"
]
]
],
"previewImage": [
"/platforms/h5/service/api/media/preview-image.js",
[
......@@ -388,36 +413,29 @@
[]
],
"onAccelerometerChange": [
"/core/service/api/device/accelerometer.js",
[
[
"/platforms/h5/service/api/device/accelerometer.js",
"enableAccelerometer"
]
]
"/platforms/h5/service/api/device/accelerometer.js",
[]
],
"offAccelerometerChange": [
"/platforms/h5/service/api/device/accelerometer.js",
[]
],
"startAccelerometer": [
"/core/service/api/device/accelerometer.js",
[
[
"/platforms/h5/service/api/device/accelerometer.js",
"enableAccelerometer"
]
]
"/platforms/h5/service/api/device/accelerometer.js",
[]
],
"stopAccelerometer": [
"/core/service/api/device/accelerometer.js",
[
[
"/platforms/h5/service/api/device/accelerometer.js",
"enableAccelerometer"
]
]
"/platforms/h5/service/api/device/accelerometer.js",
[]
],
"onCompassChange": [
"/platforms/h5/service/api/device/compass.js",
[]
],
"offCompassChange": [
"/platforms/h5/service/api/device/compass.js",
[]
],
"startCompass": [
"/platforms/h5/service/api/device/compass.js",
[]
......
{
"name": "@dcloudio/uni-h5",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app h5",
"main": "dist/index.umd.min.js",
"repository": {
......
{
"name": "@dcloudio/uni-migration",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app migration",
"main": "lib/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-mp-alipay",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app mp-alipay",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-mp-baidu",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app mp-baidu",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-mp-kuaishou",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app mp-kuaishou",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-mp-qq",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app mp-qq",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-mp-toutiao",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app mp-toutiao",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-mp-vue",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "@dcloudio/uni-mp-vue",
"main": "dist/vue.runtime.esm.js",
"module": "dist/vue.runtime.esm.js",
......
......@@ -356,111 +356,6 @@ var baseApi = /*#__PURE__*/Object.freeze({
interceptors: interceptors
});
class EventChannel {
constructor (id, events) {
this.id = id;
this.listener = {};
this.emitCache = {};
if (events) {
Object.keys(events).forEach(name => {
this.on(name, events[name]);
});
}
}
emit (eventName, ...args) {
const fns = this.listener[eventName];
if (!fns) {
return (this.emitCache[eventName] || (this.emitCache[eventName] = [])).push(args)
}
fns.forEach(opt => {
opt.fn.apply(opt.fn, args);
});
this.listener[eventName] = fns.filter(opt => opt.type !== 'once');
}
on (eventName, fn) {
this._addListener(eventName, 'on', fn);
this._clearCache(eventName);
}
once (eventName, fn) {
this._addListener(eventName, 'once', fn);
this._clearCache(eventName);
}
off (eventName, fn) {
const fns = this.listener[eventName];
if (!fns) {
return
}
if (fn) {
for (let i = 0; i < fns.length;) {
if (fns[i].fn === fn) {
fns.splice(i, 1);
i--;
}
i++;
}
} else {
delete this.listener[eventName];
}
}
_clearCache (eventName) {
const cacheArgs = this.emitCache[eventName];
if (cacheArgs) {
for (; cacheArgs.length > 0;) {
this.emit.apply(this, [eventName].concat(cacheArgs.shift()));
}
}
}
_addListener (eventName, type, fn) {
(this.listener[eventName] || (this.listener[eventName] = [])).push({
fn,
type
});
}
}
const eventChannels = {};
const eventChannelStack = [];
let id = 0;
function initEventChannel (events, cache = true) {
id++;
const eventChannel = new EventChannel(id, events);
if (cache) {
eventChannels[id] = eventChannel;
eventChannelStack.push(eventChannel);
}
return eventChannel
}
function getEventChannel (id) {
if (id) {
const eventChannel = eventChannels[id];
delete eventChannels[id];
return eventChannel
}
return eventChannelStack.shift()
}
var navigateTo = {
args (fromArgs, toArgs) {
const id = initEventChannel(fromArgs.events).id;
if (fromArgs.url) {
fromArgs.url = fromArgs.url + (fromArgs.url.indexOf('?') === -1 ? '?' : '&') + '__id__=' + id;
}
},
returnValue (fromRes, toRes) {
fromRes.eventChannel = getEventChannel();
}
};
function findExistsPageIndex (url) {
const pages = getCurrentPages();
let len = pages.length;
......@@ -527,6 +422,8 @@ var previewImage = {
}
};
// import navigateTo from 'uni-helpers/navigate-to'
function addSafeAreaInsets (result) {
if (result.safeArea) {
const safeArea = result.safeArea;
......@@ -540,7 +437,7 @@ function addSafeAreaInsets (result) {
}
const protocols = {
redirectTo,
navigateTo,
// navigateTo, // 由于在微信开发者工具的页面参数,会显示__id__参数,因此暂时关闭mp-weixin对于navigateTo的AOP
previewImage,
getSystemInfo: {
returnValue: addSafeAreaInsets
......@@ -1505,12 +1402,25 @@ function parseApp (vm) {
})
}
const eventChannels = {};
const eventChannelStack = [];
function getEventChannel (id) {
if (id) {
const eventChannel = eventChannels[id];
delete eventChannels[id];
return eventChannel
}
return eventChannelStack.shift()
}
function createApp (vm) {
Vue.prototype.getOpenerEventChannel = function () {
if (!this.__eventChannel__) {
this.__eventChannel__ = new EventChannel();
// 微信小程序使用自身getOpenerEventChannel
{
return this.$scope.getOpenerEventChannel()
}
return this.__eventChannel__
};
const callHook = Vue.prototype.__call_hook;
Vue.prototype.__call_hook = function (hook, args) {
......
{
"name": "@dcloudio/uni-mp-weixin",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app mp-weixin",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-quickapp-native",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app quickapp-native",
"main": "dist/vue.prod.js",
"repository": {
......
{
"name": "@dcloudio/uni-quickapp-webview",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app quickapp-webview",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-stat",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-template-compiler",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-template-compiler",
"main": "lib/index.js",
"repository": {
......
{
"name": "@dcloudio/vue-cli-plugin-hbuilderx",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "HBuilderX plugin for vue-cli 3",
"main": "index.js",
"repository": {
......
{
"name": "@dcloudio/vue-cli-plugin-uni-optimize",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app optimize plugin for vue-cli 3",
"main": "index.js",
"repository": {
......
{
"name": "@dcloudio/vue-cli-plugin-uni",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app plugin for vue-cli 3",
"main": "index.js",
"repository": {
......@@ -17,7 +17,7 @@
"author": "fxy060608",
"license": "Apache-2.0",
"dependencies": {
"@dcloudio/uni-stat": "^2.0.0-29320201014001",
"@dcloudio/uni-stat": "^2.0.0-alpha-29920201113004",
"buffer-json": "^2.0.0",
"copy-webpack-plugin": "^5.1.1",
"cross-env": "^5.2.0",
......
{
"name": "@dcloudio/webpack-uni-mp-loader",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "webpack-uni-mp-loader",
"main": "index.js",
"repository": {
......
{
"name": "@dcloudio/webpack-uni-pages-loader",
"version": "2.0.0-29320201014001",
"version": "2.0.0-alpha-29920201113004",
"description": "uni-app pages.json loader",
"main": "lib/index.js",
"repository": {
......@@ -21,7 +21,7 @@
"strip-json-comments": "^2.0.1"
},
"uni-app": {
"compilerVersion": "2.9.3"
"compilerVersion": "2.9.9"
},
"gitHead": "e51484a49748f7bff86bb833763e5dff1522d380"
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册