提交 5f02bcef 编写于 作者: Q qiang

Merge branch 'master' into dev

```uni-app``` 是一个使用 [Vue.js](https://vuejs.org/) 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。
`DCloud`公司拥有600万开发者用户,几十万应用案例、12亿手机端月活用户,数千款uni-app插件、70+微信/qq群。阿里小程序工具官方内置uni-app([详见](https://docs.alipay.com/mini/ide/0.70-stable)),腾讯课堂官方为uni-app录制培训课程([详见](https://ask.dcloud.net.cn/article/35640)),开发者可以放心选择。
`DCloud`公司拥有800万开发者用户,几十万应用案例、12亿手机端月活用户,数千款uni-app插件、70+微信/qq群。阿里小程序工具官方内置uni-app([详见](https://docs.alipay.com/mini/ide/0.70-stable)),腾讯课堂官方为uni-app录制培训课程([详见](https://ask.dcloud.net.cn/article/35640)),开发者可以放心选择。
`uni-app`在手,做啥都不愁。即使不跨端,```uni-app```也是更好的小程序开发框架([详见](https://ask.dcloud.net.cn/article/35947))、更好的App跨平台框架、更方便的H5开发框架。不管领导安排什么样的项目,你都可以快速交付,不需要转换开发思维、不需要更改开发习惯。
......@@ -168,14 +168,14 @@
从下面```uni-app```功能框架图可看出,```uni-app```在跨平台的过程中,不牺牲平台特色,可优雅的调用平台专有能力,真正做到海纳百川、各取所长。
![](https://img.cdn.aliyun.dcloud.net.cn/uni-app/doc/uni-app-frame-0310.png)
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-uni-app-doc/87a0a0d0-60aa-11eb-8ff1-d5dcf8779628.png)
### 一套代码,运行到多个平台
```uni-app```实现了一套代码,同时运行到多个平台;如下图所示,一套代码,同时运行到iOS模拟器、Android模拟器、H5、微信开发者工具、支付宝小程序Studio、百度开发者工具、字节跳动开发者工具、QQ开发者工具(底部8个终端选项卡代表8个终端模拟器):
![](https://img.cdn.aliyun.dcloud.net.cn/uni-app/doc/dev1x8.jpg)
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-uni-app-doc/efd8e280-60a9-11eb-a16f-5b3e54966275.jpg)
实际运行效果如下(点击图片可放大):
![](https://img.cdn.aliyun.dcloud.net.cn/uni-app/doc/run1x9.jpg)
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-uni-app-doc/4869eb60-60aa-11eb-b680-7980c8a877b8.jpg)
......@@ -22,6 +22,7 @@
* [性能优化建议](performance.md)
* [宽屏适配指南](adapt.md)
* [开放生态](ecosystem.md)
* [uni_modules插件规范](uni_modules.md)
* [从其他项目转uni-app](translate.md)
* [混合开发](hybrid.md)
* [uni小程序sdk](https://nativesupport.dcloud.net.cn/README)
......@@ -32,7 +33,6 @@
* [广告变现](uni-ad.md)
* [统一发行页面](m3w.md)
* [案例](case.md)
* [开源项目资源汇总](casecode.md)
* [选型评估指南](select.md)
* [常见问题](faq.md)
* 更新日志
......@@ -80,7 +80,7 @@
<img src="https://vkceyugu.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>21:717019120 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=cAFnn6RGFBhYzBeF6iYllRW5BCMF-9EC&jump_from=webapi">点此加入</a></div>
<div>11:296811328 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=HQE4Ze6AVxe7Gu388JQudbhEoIvVOGWj&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -95,7 +95,7 @@
<div>群24:672494800(2000人已满)</div>
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<!-- <div>群21:717019120(2000人已满)</div> -->
<div>群21:717019120(2000人已满)</div>
<div>群20:165796402(2000人已满)</div>
<div>群19:165657124(2000人已满)</div>
<div>群18:698592271(2000人已满)</div>
......@@ -105,7 +105,7 @@
<div>群14:465953250(2000人已满)</div>
<div>群13:699478442(2000人已满)</div>
<div>群12:884860657(2000人已满)</div>
<div>群11:296811328(2000人已满)</div>
<!-- <div>群11:296811328(2000人已满)</div> -->
<div>群10:959059626(2000人已满)</div>
<div>群9:775128777(2000人已满)</div>
<div>群8:695442854(2000人已满)</div>
......
......@@ -336,7 +336,7 @@ async function request () {
|[uni.showToast](api/ui/prompt?id=showtoast)|显示提示框|
|[uni.showLoading](api/ui/prompt?id=showloading)|显示加载提示框|
|[uni.hideToast](api/ui/prompt?id=hidetoast)|隐藏提示框|
|[uni.hideLoading](api/ui/prompt?id=hideloading)|隐藏提示框|
|[uni.hideLoading](api/ui/prompt?id=hideloading)|隐藏加载提示框|
|[uni.showModal](api/ui/prompt?id=showmodal)|显示模态弹窗|
|[uni.showActionSheet](api/ui/prompt?id=showactionsheet)|显示菜单列表|
##### 设置导航条
......
......@@ -178,7 +178,7 @@
<img src="https://vkceyugu.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>21:717019120 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=cAFnn6RGFBhYzBeF6iYllRW5BCMF-9EC&jump_from=webapi">点此加入</a></div>
<div>11:296811328 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=HQE4Ze6AVxe7Gu388JQudbhEoIvVOGWj&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -193,7 +193,7 @@
<div>群24:672494800(2000人已满)</div>
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<!-- <div>群21:717019120(2000人已满)</div> -->
<div>群21:717019120(2000人已满)</div>
<div>群20:165796402(2000人已满)</div>
<div>群19:165657124(2000人已满)</div>
<div>群18:698592271(2000人已满)</div>
......@@ -203,7 +203,7 @@
<div>群14:465953250(2000人已满)</div>
<div>群13:699478442(2000人已满)</div>
<div>群12:884860657(2000人已满)</div>
<div>群11:296811328(2000人已满)</div>
<!-- <div>群11:296811328(2000人已满)</div> -->
<div>群10:959059626(2000人已满)</div>
<div>群9:775128777(2000人已满)</div>
<div>群8:695442854(2000人已满)</div>
......
......@@ -24,7 +24,8 @@
| userName | string | 收货人姓名 ||
| postalCode | string | 邮编 ||
| provinceName | string | 国标收货地址第一级地址 ||
| cityName | string | 国标收货地址第一级地址 ||
| cityName | string | 国标收货地址第二级地址 ||
| countyName | string | 国标收货地址第三级地址 ||
| detailInfo | string | 详细收货地址信息 ||
| nationalCode | string | 收货地址国家码 ||
| telNumber | string | 收货人手机号码 ||
......
......@@ -40,6 +40,7 @@ uni.requestPayment是一个统一各平台的客户端支付API,不管是在
#### 注意事项
- APP端,如果你的应用在用户完成支付后;立即给支付的用户push消息通知。会与前端支付回调相互冲突,请延迟执行推送。
- 字节跳动小程序支付接口调整使用时请注意[发起头条支付](https://developer.toutiao.com/dev/cn/mini-app/develop/open-capacity/payment/pay)
#### orderInfo 注意事项@orderInfo
......
......@@ -6,7 +6,7 @@
|参数|类型|必填|默认值|说明|平台差异说明|
|:-|:-|:-|:-|:-|:-|
|url|String|是||需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 'path?key=value&key2=value2',path为下一个页面的路径,下一个页面的onLoad函数可得到传递的参数|:-|
|url|String|是||需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 'path?key=value&key2=value2',path为下一个页面的路径,下一个页面的onLoad函数可得到传递的参数| |
|animationType|String|否|pop-in|窗口显示的动画效果,详见:[窗口动画](api/router?id=animation)|App|
|animationDuration|Number|否|300|窗口动画持续时间,单位为 ms|App|
|events|Object|否||页面间通信接口,用于监听被打开页面发送到当前页面的数据。2.8.9+ 开始支持。||
......@@ -15,9 +15,9 @@
|complete|Function|否||接口调用结束的回调函数(调用成功、失败都会执行)|&nbsp;|
**object.success 回调函数**
**参数**
**Object res**
|属性|类型|说明|
......@@ -45,39 +45,39 @@ export default {
```
// 2.8.9+ 支持
uni.navigateTo({
url: 'pages/test?id=1',
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function(data) {
console.log(data)
},
someEvent: function(data) {
console.log(data)
}
...
},
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' })
}
uni.navigateTo({
url: 'pages/test?id=1',
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function(data) {
console.log(data)
},
someEvent: function(data) {
console.log(data)
}
...
},
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' })
}
})
// uni.navigateTo 目标页面 pages/test.vue
onLoad: function(option) {
console.log(option.query)
const eventChannel = this.getOpenerEventChannel()
eventChannel.emit('acceptDataFromOpenedPage', {data: 'test'});
eventChannel.emit('someEvent', {data: 'test'});
// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
eventChannel.on('acceptDataFromOpenerPage', function(data) {
console.log(data)
})
// uni.navigateTo 目标页面 pages/test.vue
onLoad: function(option) {
console.log(option.query)
const eventChannel = this.getOpenerEventChannel()
eventChannel.emit('acceptDataFromOpenedPage', {data: 'test'});
eventChannel.emit('someEvent', {data: 'test'});
// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
eventChannel.on('acceptDataFromOpenerPage', function(data) {
console.log(data)
})
}
```
url有长度限制,太长的字符串会传递失败,可使用[窗体通信](https://uniapp.dcloud.io/collocation/frame/communication)[全局变量](https://ask.dcloud.net.cn/article/35021),或`encodeURIComponent`等多种方式解决,如下为`encodeURIComponent`示例。
url有长度限制,太长的字符串会传递失败,可改用[窗体通信](https://uniapp.dcloud.io/collocation/frame/communication)[全局变量](https://ask.dcloud.net.cn/article/35021),另外参数中出现空格等特殊字符时需要对参数进行编码,如下为使用`encodeURIComponent`对参数进行编码的示例。
```html
<navigator :url="'/pages/test/test?item='+ encodeURIComponent(JSON.stringify(item))"></navigator>
```
......@@ -235,56 +235,56 @@ uni.navigateBack({
#### EventChannel.emit(string eventName, any args)
触发一个事件
string eventName
事件名称
any args
string eventName
事件名称
any args
事件参数
#### EventChannel.off(string eventName, function fn)
取消监听一个事件。给出第二个参数时,只取消给出的监听函数,否则取消所有监听函数
string eventName
事件名称
function fn
事件监听函数
参数
any args
#### EventChannel.off(string eventName, function fn)
取消监听一个事件。给出第二个参数时,只取消给出的监听函数,否则取消所有监听函数
string eventName
事件名称
function fn
事件监听函数
参数
any args
触发事件参数
#### EventChannel.on(string eventName, function fn)
持续监听一个事件
string eventName
事件名称
function fn
事件监听函数
参数
any args
#### EventChannel.on(string eventName, function fn)
持续监听一个事件
string eventName
事件名称
function fn
事件监听函数
参数
any args
触发事件参数
#### EventChannel.once(string eventName, function fn)
监听一个事件一次,触发后失效
string eventName
事件名称
function fn
事件监听函数
参数
any args
#### EventChannel.once(string eventName, function fn)
监听一个事件一次,触发后失效
string eventName
事件名称
function fn
事件监听函数
参数
any args
触发事件参数
......
......@@ -4,4 +4,6 @@
- 微信小程序平台实现参考:[规范详情](https://developers.weixin.qq.com/miniprogram/dev/api/wx.startHCE.html)
- App 平台通过Native.js实现,**安卓:**[NFC数据读取](https://ask.dcloud.net.cn/question/6726)
\ No newline at end of file
- App 平台:
1. 通过Native.js实现,**安卓:**[NFC数据读取](https://ask.dcloud.net.cn/question/6726)
2. 使用原生插件,详见[插件市场](https://ext.dcloud.net.cn/search?q=nfc)
......@@ -6,7 +6,7 @@
|参数名 |类型 |必填 |说明 |
|:- |:- |:- |:- |
|scrollTop|String | |滚动到页面的目标位置(单位px) |
|scrollTop|String | |滚动到页面的目标位置(单位px) |
|selector |String |否 |选择器,微信小程序2.7.3+ 、支付宝小程序1.20.0+支持 |
|duration |Number |否 |滚动动画的时长,默认300ms,单位 ms |
|success |function |否 |接口调用成功的回调函数 |
......
DCloud有**600万**开发者,[uni统计](https://tongji.dcloud.net.cn/)手机端月活**10亿**。是开发者数量和案例最丰富的多端开发框架。
DCloud有**800万**开发者,[uni统计](https://tongji.dcloud.net.cn/)手机端月活**12亿**。是开发者数量和案例最丰富的多端开发框架。
欢迎知名开发商[提交案例](https://github.com/dcloudio/uni-app/issues/6)或接入[uni统计](https://tongji.dcloud.net.cn/)
......
......@@ -55,7 +55,7 @@ nvue的weex编译模式中使用globalData的话,由于weex生命周期不支
globalData是简单的全局变量,如果使用状态管理,请使用`vuex`(main.js中定义)
### 全局样式
`App.vue`中,可以一些定义全局通用样式,例如需要加一个通用的背景色,首屏页面渲染的动画等都可以写在App.vue中。
`App.vue`中,可以定义一些全局通用样式,例如需要加一个通用的背景色,首屏页面渲染的动画等都可以写在App.vue中。
注意如果工程下同时有vue和nvue文件,全局样式的所有css会应用于所有文件,而nvue支持的css有限,编译器会在控制台报警,提示某些css无法在nvue中支持。此时需要把nvue不支持的css写在单独的条件编译里。如:
```html
......
......@@ -53,7 +53,7 @@
<img src="https://vkceyugu.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>21:717019120 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=cAFnn6RGFBhYzBeF6iYllRW5BCMF-9EC&jump_from=webapi">点此加入</a></div>
<div>11:296811328 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=HQE4Ze6AVxe7Gu388JQudbhEoIvVOGWj&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -68,7 +68,7 @@
<div>群24:672494800(2000人已满)</div>
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<!-- <div>群21:717019120(2000人已满)</div> -->
<div>群21:717019120(2000人已满)</div>
<div>群20:165796402(2000人已满)</div>
<div>群19:165657124(2000人已满)</div>
<div>群18:698592271(2000人已满)</div>
......@@ -78,7 +78,7 @@
<div>群14:465953250(2000人已满)</div>
<div>群13:699478442(2000人已满)</div>
<div>群12:884860657(2000人已满)</div>
<div>群11:296811328(2000人已满)</div>
<!-- <div>群11:296811328(2000人已满)</div> -->
<div>群10:959059626(2000人已满)</div>
<div>群9:775128777(2000人已满)</div>
<div>群8:695442854(2000人已满)</div>
......
......@@ -337,7 +337,7 @@ await page.waitFor(7000)
page = await program.currentPage()
```
2. 微信小程序 element 不能跨组件选择元素,首先要先获取当前组件,继续查找
2. 微信小程序 element 不能跨组件选择元素,首先要先获取当前组件,继续查找
```html
<uni-tag>
......@@ -356,6 +356,6 @@ await tag.$('.test')
3. 微信小程序暂不支持父子选择器
4. 百度小程序选择元素必须有事件的元素才能被选中,否则提示元素不存在
5. 分包中的页面,打开之后要延迟时间长一点,否不能正确获取到页面信息
5. 分包中的页面,打开之后要延迟时间长一点,否不能正确获取到页面信息
......@@ -131,7 +131,7 @@
<img src="https://vkceyugu.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>21:717019120 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=cAFnn6RGFBhYzBeF6iYllRW5BCMF-9EC&jump_from=webapi">点此加入</a></div>
<div>11:296811328 &nbsp;<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=HQE4Ze6AVxe7Gu388JQudbhEoIvVOGWj&jump_from=webapi">点此加入</a></div>
<div>群35:713420817(2000人已满)</div>
<div>群34:530305531(2000人已满)</div>
<div>群33:498071674(2000人已满)</div>
......@@ -146,7 +146,7 @@
<div>群24:672494800(2000人已满)</div>
<div>群23:599958679(2000人已满)</div>
<div>群22:687186952(2000人已满)</div>
<!-- <div>群21:717019120(2000人已满)</div> -->
<div>群21:717019120(2000人已满)</div>
<div>群20:165796402(2000人已满)</div>
<div>群19:165657124(2000人已满)</div>
<div>群18:698592271(2000人已满)</div>
......@@ -156,7 +156,7 @@
<div>群14:465953250(2000人已满)</div>
<div>群13:699478442(2000人已满)</div>
<div>群12:884860657(2000人已满)</div>
<div>群11:296811328(2000人已满)</div>
<!-- <div>群11:296811328(2000人已满)</div> -->
<div>群10:959059626(2000人已满)</div>
<div>群9:775128777(2000人已满)</div>
<div>群8:695442854(2000人已满)</div>
......
......@@ -101,7 +101,7 @@
<!-- 仅nvue页面支持 -->
<view class="content">
<view class="ad-draw">
<ad-draw :adData="adData" @load="onload" @error="onerror"></ad-draw>
<ad-draw :data="adData" @load="onload" @error="onerror"></ad-draw>
</view>
</view>
</template>
......@@ -115,6 +115,7 @@
}
},
onReady: function (e) {
this.getAdData()
},
methods: {
getAdData: function (e) {
......
### 激励视频广告
文档地址已迁移至:[https://uniapp.dcloud.io/api/ad/rewarded-video-ad/](https://uniapp.dcloud.io/api/ad/rewarded-video-ad)
\ No newline at end of file
文档地址已迁移至:[https://uniapp.dcloud.io/api/ad/rewarded-video](https://uniapp.dcloud.io/api/ad/rewarded-video)
\ No newline at end of file
......@@ -192,6 +192,7 @@ export default {
width: 300 // 根据宽度获取合适的广告(单位px)
},
(res) => {
// 注意: 广告数据只能使用一次
this.adData = res.ads[0];
console.log(this.adData);
},
......
......@@ -350,3 +350,469 @@ datacom组件规范还要求支持绑定 value,且支持双向绑定,即:
|tree(树状控件) |单选、多选 |树 |平铺 |展示 | |
欢迎开发者们开发这些`datacom组件`,后续插件市场将单列出datacom组件,给予更高的显示权重。
### 使用mixinDatacom快速开发datacom@mixindatacom
> 版本要求:HBuilderX 3.1.0+
开发一个支持localdata的datacom组件相对容易,但要开发支持云端数据的datacom组件,实现对collection、field、where等属性的解析,工作量还是不小的。
为此官方提供了一个mixin混入库,开发者在自己的datacom组件中混入`uniCloud.mixinDatacom`,即可方便的让自己的组件支持本地和云端的数据绑定,快速完成datacom组件。
mixin是vue的技术,不熟悉的可以点此了解[vue官网的mixin文档](https://cn.vuejs.org/v2/api/#Vue-mixin)
#### 语法手册
`uniCloud.mixinDatacom` 的props
与标准的datacom组件相同,除了localdata外,其他都是`uniCloud-db组件`的标准属性。
|属性名 | 类型 | 默认值 | 说明|
|:-: | :-: | :-: | :-: |
|localdata |Array | |本地数据,[详情](https://uniapp.dcloud.net.cn/component/datacom)|
|collection |String | |表名。支持输入多个表名,用 `,` 分割|
|field |String | |查询字段,多个字段用 `,` 分割|
|where |String | |查询条件,内容较多,另见jql文档:[详情](https://uniapp.dcloud.net.cn/uniCloud/uni-clientDB?id=jsquery)|
|orderby |String | |排序字段及正序倒叙设置|
|groupby |String | |对数据进行分组|
|group-field |String | |对数据进行分组统计|
|distinct |Boolean | false |是否对数据查询结果中重复的记录进行去重|
|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|
|page-data |String | add |分页策略选择。值为 `add` 代表下一页的数据追加到之前的数据中,常用于滚动到底加载下一页;值为 `replace` 时则替换当前data数据,常用于PC式交互,列表底部有页码分页按钮|
|page-current |Number | 0 |当前页|
|page-size |Number | 10 |每页数据数量|
|getcount |Boolean | false |是否查询总数据条数,默认 `false`,需要分页模式时指定为 `true`|
|getone |Boolean | false |指定查询结果是否仅返回数组第一条数据,默认 false。在false情况下返回的是数组,即便只有一条结果,也需要[0]的方式获取。在值为 true 时,直接返回结果数据,少一层数组。一般用于非列表页,比如详情页|
|gettree |Boolean | false |是否查询树状数据,默认 `false`|
|startwith |String | '' |`gettree`的第一层级条件,此初始条件可以省略,不传startWith时默认从最顶级开始查询|
|limitlevel |Number | 10 |`gettree`查询返回的树的最大层级。超过设定层级的节点不会返回。默认10级,最大15,最小1|
`uniCloud.mixinDatacom` 的data
|属性名 | 类型 | 默认值 | 说明|
|:-: | :-: | :-: | :-: |
|mixinDatacomLoading |Boolean | false |加载数据状态|
|mixinDatacomHasMore |Boolean | false |是否有更多数据|
|mixinDatacomResData |Array | [] |查询返回的数据|
|mixinDatacomErrorMessage |String | |错误消息|
|mixinDatacomPage |OBject | |分页信息|
`uniCloud.mixinDatacom` methods
|方法名 | 说明|
|:-: | :-: |
|mixinDatacomGet |加载数据|
|mixinDatacomEasyGet |加载数据,包含 `mixinDatacomLoading``mixinDatacomHasMore``mixinDatacomErrorMessage` 逻辑 |
|onMixinDatacomPropsChange |属性发生变化时触发|
#### 使用方法
使用 `uniCloud.mixinDatacom` 开发 `datacom` 组件需要以下步骤
1. 在export default下声明`mixin: [uniCloud.mixinDatacom]`
2. 在template中定义三个标签,绑定 `uniCloud.mixinDatacom``data` 状态,加载中`mixinDatacomLoading` 、加载出错提示 `mixinDatacomErrorMessage`、处理数据及相关UI展现 `mixinDatacomResData`
3. 组件的created声明周期中调用 `uniCloud.mixinDatacom` 中的 `mixinDatacomGet()``mixinDatacomEasyGet()` 方法请求云端数据库。这两种方法的区别如下:
- `mixinDatacomGet()` 仅请求数据,自行处理各种状态和异常。
- `mixinDatacomEasyGet()``mixinDatacomGet()` 的基础之上封装了加载状态、分页及错误消息,可通过模板绑定。用起来更简单
使用 `uniCloud.mixinDatacom` 开发 `datacom` 组件的优势
- 不需要定义 `datacom` 组件的属性
- 不需要关心 `uniClinetDB` API
- 不需要判断哪些属性变化时需要重置已加载数据, 仅判断 `onMixinDatacomPropsChange(needReset, changed) {}` 参数 `needReset` 是否为 `true` 即可
-`uniClinetDB` 有新增属性时,组件代码也不需要跟随更新
例如要开发一个datacom组件,名为uni-data-jql:
- 方法1,使用 `mixinDatacomEasyGet()`
```html
<!-- uni-data-jql.vue -->
<template>
<view>
<view v-if="mixinDatacomLoading">Loading...</view>
<view v-else-if="mixinDatacomErrorMessage">
请求错误:{{mixinDatacomErrorMessage}}
</view>
<view else="mixinDatacomResData">
<!-- 需要自行处理数据及相关UI展现 -->
{{mixinDatacomResData}}
</view>
</view>
</template>
<script>
export default {
mixins: [uniCloud.mixinDatacom],
data() {
return {}
},
created() {
// 调用 uniCloud.mixinDatacom 中的方法加载数据
this.mixinDatacomEasyGet()
},
methods: {
// 当组件属性发生变化时
onMixinDatacomPropsChange(needReset, changed) {
// needReset=true 需要重置已加载数据和分页信息,例如 collection,orderby
// changed,变化的属性名,类型为 Array,例如 ['collection', 'orderby']
if (needReset) {
// 清空已加载的数据
this.mixinDatacomResData = []
// 重置分页数据,如果没有分页不需要处理
this.mixinDatacomPage.size = this.pageSize // 重置分页大小
this.mixinDatacomPage.current = 0 // 重置当前分页
this.mixinDatacomPage.count = 0 // 重置数据总数
}
}
}
}
</script>
```
- 方法2,使用 `mixinDatacomGet()`
需要多写些代码处理各种状态。如果`mixinDatacomEasyGet`的封装无法灵活满足你的需求,可以使用这种方式。
```html
<!-- uni-data-jql.vue -->
<template>
<view>
<view v-if="mixinDatacomLoading">Loading...</view>
<view v-else-if="mixinDatacomErrorMessage">
请求错误:{{mixinDatacomErrorMessage}}
</view>
<view else="mixinDatacomResData">
<!-- 需要自行处理数据及相关UI展现 -->
{{mixinDatacomResData}}
</view>
</view>
</template>
<script>
export default {
mixins: [uniCloud.mixinDatacom],
data() {
return {}
},
created() {
this.load()
},
methods: {
load() {
if (this.mixinDatacomLoading == true) {
return
}
this.mixinDatacomLoading = true
this.mixinDatacomGet().then((res) => {
this.mixinDatacomLoading = false
const {
data,
count
} = res.result
this.mixinDatacomResData = data
}).catch((err) => {
this.mixinDatacomLoading = false
this.mixinDatacomErrorMessage = err
})
},
// 当组件属性发生变化时
onMixinDatacomPropsChange(needReset, changed) {
// needReset=true 需要重置已加载数据和分页信息,例如 collection,orderby
// changed,变化的属性名,类型为 Array,例如 ['collection', 'orderby']
if (needReset) {
// 清空已加载的数据
this.mixinDatacomResData = []
// 重置分页数据,如果没有分页不需要处理
this.mixinDatacomPage.size = this.pageSize // 重置分页大小
this.mixinDatacomPage.current = 0 // 重置当前分页
this.mixinDatacomPage.count = 0 // 重置数据总数
}
}
}
}
</script>
```
做好这个uni-data-jql组件后,就可以在页面中使用了:
```html
<template>
<view>
<uni-data-jql collection="table1"></uni-data-jql>
</view>
</template>
<script>
// jql.vue 组件
import UniData from "./jql.vue" // 如果符合easycom规范,无需本代码
export default {
components: {
UniData // 如果符合easycom规范,无需本代码
},
data() {
return {}
},
methods: {}
}
</script>
```
#### `uniCloud.mixinDatacom` 源码 @mixinDatacomsource
为方便开发者理解mixinDatacom的工作原理,这里贴出mixinDatacom的源码:
```js
export default {
props: {
localdata: {
type: Array,
default () {
return []
}
},
options: {
type: [Object, Array],
default () {
return {}
}
},
collection: {
type: String,
default: ''
},
action: {
type: String,
default: ''
},
field: {
type: String,
default: ''
},
orderby: {
type: String,
default: ''
},
where: {
type: [String, Object],
default: ''
},
pageData: {
type: String,
default: 'add'
},
pageCurrent: {
type: Number,
default: 1
},
pageSize: {
type: Number,
default: 20
},
getcount: {
type: [Boolean, String],
default: false
},
gettree: {
type: [Boolean, String],
default: false
},
gettreepath: {
type: [Boolean, String],
default: false
},
startwith: {
type: String,
default: ''
},
limitlevel: {
type: Number,
default: 10
},
groupby: {
type: String,
default: ''
},
groupField: {
type: String,
default: ''
},
distinct: {
type: [Boolean, String],
default: false
},
manual: {
type: Boolean,
default: false
}
},
data() {
return {
mixinDatacomLoading: false, // 网络请求状态
mixinDatacomHasMore: false, // 是否有更多数据
mixinDatacomResData: [], // 请求返回的数据,调用 loadData 后会更新
mixinDatacomErrorMessage: '', // 请求出错时的错误消息
mixinDatacomPage: {} // 分页信息,详情见 created 生命周期
}
},
created() {
this.mixinDatacomPage = {
current: this.pageCurrent, // 当前页面,初始化设置 props中的 pageCurrent
size: this.pageSize, // 页面大小,初始化设置 props中的 pageSize
count: 0, // 数据总数,getcount=true时有效
}
this.$watch(() => {
var al = [];
['pageCurrent',
'pageSize',
'localdata',
'collection',
'action',
'field',
'orderby',
'where',
'getont',
'getcount',
'gettree'
].forEach(key => {
al.push(this[key])
})
return al
}, (newValue, oldValue) => {
let needReset = false
let changed = []
for (let i = 2; i < newValue.length; i++) {
if (newValue[i] !== oldValue[i]) {
needReset = true
changed.push(newValue[i])
}
}
if (newValue[0] !== oldValue[0]) {
this.mixinDatacomPage.current = this.pageCurrent
}
this.mixinDatacomPage.size = this.pageSize
this.onMixinDatacomPropsChange(needReset, changed)
})
},
methods: {
// props发生变化时被调用,在组件中覆盖此方法
// 非 pageCurrent,pageSize 改变时 needReset=true,需要重置数据
// changed,发生变化的属性名,类型为Array,例如 ['collection', 'action']
onMixinDatacomPropsChange(needReset, changed) {},
// 加载数据
mixinDatacomEasyGet({
getone = false,
success,
fail
} = {}) {
if (this.mixinDatacomLoading) {
return
}
this.mixinDatacomLoading = true
this.mixinDatacomErrorMessage = ''
this.mixinDatacomGet().then((res) => {
this.mixinDatacomLoading = false
const {
data,
count
} = res.result
if (this.getcount) {
this.mixinDatacomPage.count = count
}
this.mixinDatacomHasMore = data.length < this.pageSize
const responseData = getone ? (data.length ? data[0] : undefined) : data
this.mixinDatacomResData = responseData
if (success) {
success(responseData)
}
}).catch((err) => {
this.mixinDatacomLoading = false
this.mixinDatacomErrorMessage = err
fail && fail(err)
})
},
// 调用 uniClientDB 查询数据
mixinDatacomGet(options = {}) {
let db = uniCloud.database()
const action = options.action || this.action
if (action) {
db = db.action(action)
}
const collection = options.collection || this.collection
db = db.collection(collection)
const where = options.where || this.where
if (!(!where || !Object.keys(where).length)) {
db = db.where(where)
}
const field = options.field || this.field
if (field) {
db = db.field(field)
}
const groupby = options.groupby || this.groupby
if (groupby) {
db = db.groupBy(groupby)
}
const groupField = options.groupField || this.groupField
if (groupField) {
db = db.groupField(groupField)
}
const distinct = options.distinct !== undefined ? options.distinct : this.distinct
if (distinct === true) {
db = db.distinct()
}
const orderby = options.orderby || this.orderby
if (orderby) {
db = db.orderBy(orderby)
}
const current = options.pageCurrent !== undefined ? options.pageCurrent : this.mixinDatacomPage.current
const size = options.pageSize !== undefined ? options.pageSize : this.mixinDatacomPage.size
const getCount = options.getcount !== undefined ? options.getcount : this.getcount
const gettree = options.gettree !== undefined ? options.gettree : this.gettree
const gettreepath = options.gettreepath !== undefined ? options.gettreepath : this.gettreepath
const limitLevel = options.limitlevel !== undefined ? options.limitlevel : this.limitlevel
const startWith = options.startwith !== undefined ? options.startwith : this.startwith
const getOptions = {
getCount
}
const treeOptions = {
limitLevel,
startWith
}
if (gettree) {
getOptions.getTree = treeOptions
}
if (gettreepath) {
getOptions.getTreePath = treeOptions
}
db = db.skip(size * (current - 1)).limit(size).get(getOptions)
return db
}
}
}
```
......@@ -15,7 +15,7 @@
|disabled|Boolean|false|是否禁用||
|maxlength|Number|140|最大输入长度,设置为 -1 的时候不限制最大长度||
|cursor-spacing|Number|0|指定光标与键盘的距离,单位 px 。取 input 距离底部的距离和 cursor-spacing 指定的距离的最小值作为光标与键盘的距离|App、微信小程序、百度小程序、QQ小程序|
|focus|Boolean|false|获取焦点。|在 H5 平台能否聚焦以及软键盘是否跟随弹出,取决于当前浏览器本身的实现。|
|focus|Boolean|false|获取焦点。|在 H5 平台能否聚焦以及软键盘是否跟随弹出,取决于当前浏览器本身的实现。nvue 页面不支持,需使用组件的 focus()、blur() 方法控制焦点|
|confirm-type|String|done|设置键盘右下角按钮的文字,仅在 type="text" 时生效。|微信小程序、App、H5|
|confirm-hold|Boolean|false|点击键盘右下角按钮时是否保持键盘不收起|App、微信小程序、支付宝小程序、百度小程序、QQ小程序|
|cursor|Number||指定focus时的光标位置||
......
......@@ -76,7 +76,8 @@ headerHeight|吸顶距离|Number|是|子list吸顶距离最外层滚动容器顶
如果列表滚动到底部将会立即触发这个事件,你可以在这个事件的处理函数中加载下一页的列表项。 如果未触发,请检查是否设置了loadmoreoffset的值,建议此值设置大于0
- 如何重置 loadmore
```
```html
<template>
<list ref="list">
<cell v-for="num in lists">
......@@ -133,13 +134,32 @@ headerHeight|float|0|是|要吸顶的header顶部距离scroller顶部的距离
#### 示例:
```html
<template>
<!-- ios 需要配置 fixFreezing="true" -->
<view class="uni-swiper-page">
<list ref="list" fixFreezing="true">
</list>
</view>
</template>
<script>
export default {
data () {
return {
}
},
methods: {
// 重置 loadmore
setSpecialEffects() {
this.$refs["list"].setSpecialEffects({id:"scroller", headerHeight:150});
},
clearSpecialEffects() {
this.$refs["list"].setSpecialEffects({});
}
}
}
</script>
```
<list id="" fixFreezing="true"></list>
// ios 需要配置 fixFreezing="true"
//设置
const list = this.$refs["list0"];
list.setSpecialEffects({id:"scroller", headerHeight:150});
//清除
list.setSpecialEffects({});
```
`setSpecialEffects` 完整代码: [https://github.com/dcloudio/hello-uniapp/tree/master/pages/template/swiper-list-nvue](https://github.com/dcloudio/hello-uniapp/tree/master/pages/template/swiper-list-nvue)
......@@ -16,7 +16,10 @@
|:-|:-|:-|:-|:-|
|longitude|Number||中心经度||
|latitude|Number||中心纬度||
|scale|Number|16|缩放级别,取值范围为5-18||
|scale|Number|16|缩放级别,取值范围为3-20|高德地图缩放比例与微信小程序不同|
|min-scale|Number|3|最小缩放级别|App-nvue 3.1.0+、微信小程序2.13+|
|max-scale|Number|20|最大缩放级别|App-nvue 3.1.0+、微信小程序2.13+|
|layer-style|Number|1|个性化地图|App-nvue 3.1.0+、微信小程序2.13+|
|markers|Array||标记点||
|polyline|Array||路线||
|circles|Array||圆||
......@@ -30,8 +33,11 @@
|enable-overlooking|Boolean|false|是否开启俯视|App-nvue 2.1.5+、微信小程序2.3.0|
|enable-satellite|Boolean|false|是否开启卫星图|App-nvue 2.1.5+、微信小程序2.7.0|
|enable-traffic|Boolean|false|是否开启实时路况|App-nvue 2.1.5+、微信小程序2.7.0|
|enable-poi|Boolean|false|是否展示 POI 点|App-nvue 3.1.0+|
|enable-building|Boolean|false|是否展示建筑物|App-nvue 3.1.0+ 支持 (**废除原enable-3D属性 高德地图默认开启建筑物就是3D无法设置**)|
|show-location|Boolean||显示带有方向的当前定位点|微信小程序、H5、百度小程序、支付宝小程序|
|polygons|Array.`<polygon>`||多边形|App-nvue 2.1.5+、微信小程序、百度小程序、支付宝小程序|
|enable-indoorMap|Boolean|false|是否展示室内地图|App-nvue 3.1.0+|
|@markertap|EventHandle||点击标记点时触发,e.detail = {markerId}|App-nvue 2.3.3+, App平台需要指定 marker 对象属性 id|
|@labeltap|EventHandle||点击label时触发,e.detail = {markerId} |微信小程序2.9.0|
|@callouttap|EventHandle||点击标记点对应的气泡时触发,e.detail = {markerId}||
......@@ -39,11 +45,13 @@
|@regionchange|EventHandle||视野发生变化时触发|微信小程序、H5、百度小程序、支付宝小程序|
|@tap|EventHandle||点击地图时触发; App-nuve、微信小程序2.9支持返回经纬度||
|@updated|EventHandle||在地图渲染更新完成时触发|微信小程序、H5、百度小程序|
|@anchorpointtap|EventHandle||点击定位标时触发,e.detail = {longitude, latitude}|App-nvue 3.1.0+、微信小程序2.13+|
**注意**
- `<map>` 组件的宽/高推荐写直接量,比如:750rpx,不要设置百分比值。
- `uni-app` 只支持 `gcj02` 坐标
- App平台 `layer-style` 属性需要在地图服务商后台创建,[详情](https://developer.amap.com/api/android-sdk/guide/create-map/custom)
**markers**
......@@ -63,6 +71,10 @@
|callout|自定义标记点上方的气泡窗口|Object|否|支持的属性见下表,可识别换行符。|App-nvue 2.1.5+|
|label|为标记点旁边增加标签|Object|否|支持的属性见下表,可识别换行符。|App-nvue 2.1.5+、微信小程序、H5、App、百度小程序|
|anchor|经纬度在标注图标的锚点,默认底边中点|Object|否|{x, y},x表示横向(0-1),y表示竖向(0-1)。{x: .5, y: 1} 表示底边中点|App-nvue 2.1.5+、微信小程序、H5、百度小程序|
|joinCluster|是否参与点聚合|Boolean|否||App-nvue 3.1.0+、微信小程序|
|clusterId|自定义点聚合簇效果时使用|Number|否||App-nvue 3.1.0+、微信小程序|
|customCallout|自定义气泡窗口|Object|否||app暂时不支持、微信小程序|
|aria-label|无障碍访问,(属性)元素的额外描述|String|否||App-nvue 3.1.0+、微信小程序|
**marker 上的气泡 callout**
......@@ -92,6 +104,10 @@
|bgColor|背景色|String|App-nvue 2.1.5+、微信小程序、百度小程序|
|padding|文本边缘留白|Number|App-nvue 2.1.5+、微信小程序、百度小程序|
|textAlign|文本对齐方式。有效值: left, right, center|String|App-nvue 2.1.5+、微信小程序、百度小程序|
|joinCluster|是否参与点聚合|Boolean|App-nvue 3.1.0+、微信小程序|
|clusterId|自定义点聚合簇效果时使用|Number|App-nvue 3.1.0+、微信小程序|
|customCallout|自定义气泡窗口|Object|App暂时不支持、微信小程序|
|aria-label|无障碍访问,(属性)元素的额外描述|String|App-nvue 3.1.0+、微信小程序|
**polyline**
......@@ -107,6 +123,8 @@
|arrowIconPath|更换箭头图标|String|否|在arrowLine为true时生效|App-nvue 2.1.5+、微信小程序、百度小程序|
|borderColor|线的边框颜色|String|否||App-nvue 2.1.5+、微信小程序、H5、百度小程序|
|borderWidth|线的厚度|Number|否||App-nvue 2.1.5+、微信小程序、H5、百度小程序|
|colorList|彩虹线|Array|false|存在时忽略 color 值|App-nvue 3.1.0+、微信小程序|
|level|压盖关系,默认为 abovelabels|String|false||App不支持(**需SDK提供支持**)、微信小程序|
**polygon**<br>
指定一系列坐标点,根据 points 坐标数据生成闭合多边形
......@@ -118,6 +136,7 @@
|strokeColor|描边的颜色|String|否|十六进制|
|fillColor|填充颜色|String|否|十六进制|
|zIndex|设置多边形 Z 轴数值|Number|否||
|level|压盖关系,默认为 abovelabels|String|false|App不支持(**需SDK提供支持**)、微信小程序|
**circles**
......@@ -131,6 +150,7 @@
|fillColor|填充颜色|String|否|8位十六进制表示,后两位表示alpha值,如:#0000AA|
|radius|半径|Number|是||
|strokeWidth|描边的宽度|Number|否|&nbsp;|
|level|压盖关系,默认为 abovelabels|String|false|App不支持(**需SDK提供支持**)、微信小程序|
**controls**
......
......@@ -48,6 +48,7 @@ change 事件返回 detail 中包含一个 source 字段,表示导致变更的
**Tips**
- 如果 nvue 页面 ``@animationfinish`` 事件不能返回正确的数据,可同时监听 ``@change`` 事件。
- 使用竖向滚动时,需要给 ``<scroll-view>`` 一个固定高度,通过 css 设置 height。
- 注意:其中只可放置 ``<swiper-item>`` 组件,否则会导致未定义的行为。
- 如果遇到current、current-item-id属性设置不生效的问题参考:[组件属性设置不生效解决办法](/vue-api?id=_4-组件属性设置不生效解决办法)
......
......@@ -12,7 +12,7 @@
|placeholder-class|String|textarea-placeholder|指定 placeholder 的样式类,注意页面或组件的style中写了scoped时,需要在类名前写/deep/|字节跳动小程序不支持|
|disabled|Boolean|false|是否禁用||
|maxlength|Number|140|最大输入长度,设置为 -1 的时候不限制最大长度||
|focus|Boolean|false|获取焦点|在 H5 平台能否聚焦以及软键盘是否跟随弹出,取决于当前浏览器本身的实现。|
|focus|Boolean|false|获取焦点|在 H5 平台能否聚焦以及软键盘是否跟随弹出,取决于当前浏览器本身的实现。nvue 页面不支持,需使用组件的 focus()、blur() 方法控制焦点|
|auto-height|Boolean|false|是否自动增高,设置auto-height时,style.height不生效||
|fixed|Boolean|false|如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true|微信小程序、百度小程序、字节跳动小程序、QQ小程序|
|cursor-spacing|Number|0|指定光标与键盘的距离,单位 px 。取 textarea 距离底部的距离和 cursor-spacing 指定的距离的最小值作为光标与键盘的距离|App、微信小程序、百度小程序、字节跳动小程序、QQ小程序|
......
......@@ -24,10 +24,10 @@
注意:
* 发行混合分包后,App.vue中的onLaunch,onShow等应用级别生命周期不再触发
* 发行混合分包后,App.vue中的onLaunch会在首次进入分包时触发(HBuilderX 3.1.1+)
* 开发时需要将资源(图片,css,js等)、页面的绝对路径调整为相对路径,否则打包到原生小程序中时,可能出现路径查找错误。
* 需要自己把页面或分包配置添加到已有小程序的app.json中。
* 目前支持微信小程序,百度小程序,字节跳动小程序,QQ小程序。
* 目前支持微信小程序,百度小程序,支付宝小程序,字节跳动小程序,QQ小程序。
* 三方开发者插件,[参考](https://ext.dcloud.net.cn/plugin?id=1560)
......
......@@ -40,6 +40,9 @@ nvue的组件和API写法与vue页面一致,其内置组件还比vue页面内
2. 动态横竖屏。nvue页面的css不支持媒体查询,所以横竖屏动态切换、动态适配屏幕是很困难的。
## 纯原生渲染模式
uni-app在App端,支持vue页面和nvue页面混搭、互相跳转。也支持纯nvue原生渲染。
......@@ -153,6 +156,45 @@ weex 编译模式下支持使用 weex ui ,例子[详见](https://ext.dcloud.ne
HBuilderX内置了weex调试工具的强化版,包括审查界面元素、看log、debug打断点,[详见](https://uniapp.dcloud.io/snippet?id=%e5%85%b3%e4%ba%8e-app-%e7%9a%84%e8%b0%83%e8%af%95)
## render-whole
在HBuilder X 3.1.0起版本,nvue 新增 `render-whole`属性,类型`Boolean`。
- 设置render-whole="true"时,视图层将组件以及子组件的信息结构一次性和原生层通讯,通过整个节点的重绘提升了排版渲染性能。
- 设置render-whole="false"时,视图层将以子节点一个接着一个和原生层通讯再重绘。总体的渲染时间可能更久。
默认启用`render-whole`为`true`的组件列表
- `text`
- `cell`
- `header`
- `cell-slot`
- `recycle-list`
**使用**
```html
<swiper :render-whole="true"></swiper>
```
**演示**
> 此演示在Android 5.1版本手机上的效果,高版本手机效果没有这么明显
<img style="width:300px;" src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/29c0c580-55ab-11eb-a16f-5b3e54966275.gif"></img>
示例工程[点击下载](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d5adb160-55af-11eb-bd01-97bc1429a9ff.zip)
## nvue开发与vue开发的常见区别
基于原生引擎的渲染,虽然还是前端技术栈,但和web开发肯定是有区别的。
......
......@@ -25,7 +25,7 @@ h5和小程序平台,以及app-vue,视图层是webview。而app-nvue的视
Android上小程序大多自带了一个几十M的chromium webview,而App端没办法带这么大体积的三方包,所以App端默认使用了Android system webview,这个系统webview跟随手机不同而有差异。当然App端也支持使用腾讯X5引擎,此时可以在Android端统一视图层。
所以uni-app的js基本没有不同手机的兼容问题(因为js引擎自带了),而视图层的css,在app-vue上使用系统webview时会有手机浏览器的css兼容问题。此时或者不要用太的css语法,或者集成腾讯x5引擎。
所以uni-app的js基本没有不同手机的兼容问题(因为js引擎自带了),而视图层的css,在app-vue上使用系统webview时会有手机浏览器的css兼容问题。此时或者不要用太的css语法,或者集成腾讯x5引擎。
###### 逻辑层和视图层分离的利与弊
......
此差异已折叠。
此差异已折叠。
......@@ -4,6 +4,11 @@
[HBuilderX 2.5.8](https://www.dcloud.io/hbuilderx.html)起支持。阿里云、腾讯云均已开放注册使用。
<video style="width:100vw;height:56.25vw;" id="video" preload="none" controls="controls"
poster="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-a90b5f95-90ba-4d30-a6a7-cd4d057327db/24cc615a-95c6-4bff-933b-0a3d68bcc55a.mp4?x-oss-process=video/snapshot,t_1000,f_jpg" src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-a90b5f95-90ba-4d30-a6a7-cd4d057327db/24cc615a-95c6-4bff-933b-0a3d68bcc55a.mp4"></video>
[更多视频教程](https://study.163.com/course/courseLearn.htm?courseId=1209978085#/learn/video?lessonId=1280845026&courseId=1209978085)
### uniCloud 的价值
- 对于程序员,从此你又get一个新技能,用熟悉的js,轻松搞定前后台整体业务。
......
......@@ -9,9 +9,11 @@
* [云数据库入门](uniCloud/hellodb.md)
* [云函数操作云数据库](uniCloud/cf-database.md)
* [DB Schema表结构](uniCloud/schema.md)
* [数据库索引](uniCloud/db-index.md)
* [前端操作数据库的API及JQL语法](uniCloud/clientdb.md)
* [unicloud-db前端组件](uniCloud/unicloud-db.md)
* [openDB](https://gitee.com/dcloud/opendb)
* [性能优化](uniCloud/db-performance.md)
* 云函数
* [开发云函数](uniCloud/cf-functions.md)
* [云函数公共模块](uniCloud/cf-common.md)
......@@ -23,6 +25,7 @@
* [云存储](uniCloud/storage.md)
* [腾讯云自定义登录](uniCloud/authentication.md)
* [腾讯云权限管理](uniCloud/policy-tcb.md)
* [客户端sdk](uniCloud/client-sdk.md)
* [uni-id用户体系](uniCloud/uni-id.md)
* 扩展能力
* [uniCloud admin](uniCloud/admin.md)
......@@ -31,6 +34,7 @@
* [发送短信](uniCloud/send-sms.md)
* [uni一键登录](uniCloud/univerify.md)
* [云端一体搜索](https://ext.dcloud.net.cn/plugin?id=3851)
* [uni-captcha图形验证码](https://ext.dcloud.net.cn/plugin?id=4048)
* [前端网页托管](uniCloud/hosting.md)
* [日志输出](uniCloud/cf-logger.md)
* [同时连多服务空间](uniCloud/init.md)
......
......@@ -6,25 +6,36 @@ uniCloud admin 框架,是基于 uni-app 和 uniCloud 的应用后台管理的
对于uniCloud的开发者而言,其后台管理系统应该使用本框架。
版本支持:HBuilderX 2.9.5+
版本支持:HBuilderX 3.0+
下载地址:[https://ext.dcloud.net.cn/plugin?id=3268](https://ext.dcloud.net.cn/plugin?id=3268)
- 它基于 uni-app 的宽屏适配,可自动适配 PC 宽屏和手机各端。了解[宽屏适配](https://uniapp.dcloud.io/adapt)
- 它基于 uniCloud,是 serverless 的云开发。了解[uniCloud](https://uniapp.dcloud.io/uniCloud/README)
- 它基于 uni-id,使用 uni-id 的用户账户、角色、权限系统。了解[uni-id](https://uniapp.dcloud.io/uniCloud/uni-id)
### 内置的功能
### uniCloud admin 功能介绍
uniCloud admin有预置功能、插件生态和数据表管理的代码生成工具。
有这套组合,管理端系统的开发变的前所未有的简单、高效、低成本。
1. 预置功能
- 管理员账户初始化、登录、修改密码
- 基于uni-id的用户管理(注册、修改信息、停用启用、删除)、角色管理、权限管理
- 顶部 topWindow 的设置:比如 logo 更换、右上角部分链接更换。详见项目根目录的`admin.config.js`文件
- 左侧 leftWindow 的菜单设置:菜单包括两类,一类是动态菜单,具备业务和权限功能;另一类是静态菜单,不会根据登录用户角色变化
- 动态菜单的数据存储在数据库表opendb-admin-menus中,基于uni-id角色权限,在菜单管理中可以对菜单进行增删改查
- 开发模式下的 debug 功能,帮助开发者及时发现报错和搜索错误信息,可在`admin.config.js`文件中配置
2. 扩展插件
- uniCloud admin支持插件生态,包括cms插件、banner管理插件、日志管理插件、图表示例等,详见[插件市场](https://ext.dcloud.net.cn/?cat1=7&cat2=74&orderBy=UpdatedDate)
3. 数据表管理的代码生成工具
- 对于数据表的管理,如列表浏览、分页搜索、详情修改、新增删除,这些代码都无需自己开发。建好数据表的schema表结构,利用schema2code工具,即可自动生成该表的管理页面的代码。详见[schema2code](https://uniapp.dcloud.net.cn/uniCloud/schema?id=autocode)
除了内置功能,uniCloud admin支持插件生态,在[插件市场](https://ext.dcloud.net.cn/?cat1=7&cat2=74&orderBy=UpdatedDate)可以找到更多现成的轮子拿来即用,比如cms等
uniCloud admin是完整开源的一个uni-app项目,任何熟悉uni-app的工程师都可以自行开发扩展功能
### 支持响应式布局
uniCloud admin 同时支持 PC 端 和移动端。
uniCloud admin 同时支持 PC 端 和移动端。基础模块是全端可用的,但注意有的插件不是全端的。
PC 端如下图:
......@@ -40,7 +51,7 @@ PC 端如下图:
#### 创建
[HBuilderX](https://www.dcloud.io/hbuilderx.html) 2.9.5+版本新建 uni-app 项目,选择 uniCloud admin 项目模板,如下图
[HBuilderX](https://www.dcloud.io/hbuilderx.html) 3.0+版本新建 uni-app 项目,选择 uniCloud admin 项目模板,如下图
![download-admin](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2085840-15db-11eb-880a-0db19f4f74bb.png)
......@@ -48,20 +59,21 @@ PC 端如下图:
![download-admin](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2baaddd0-11f5-11eb-81ea-f115fe74321c.png)
除了可视化向导外,也可以从[https://github.com/dcloudio/uniCloud-admin](https://github.com/dcloudio/uniCloud-admin)获取代码。
<!-- 除了可视化向导外,也可以从[https://github.com/dcloudio/uniCloud-admin](https://github.com/dcloudio/uniCloud-admin)获取代码。 -->
#### 运行
1. 进入 admin 项目
2./cloudfunctions-aliyun/common/uni-id/config.json 文件中填写 `passwordSecret` 字段 (用于加密密码入库的密钥) 和 `tokenSecret` 字段 (为生成 token 需要的密钥)
3. 右键 cloudfuntions 运行云服务空间初始化向导(如已创建并绑定云服务空间,则跳过此步)
4. 点击HBuilderX工具栏的运行【Ctrl+r】 -> 运行到浏览器
2.uniCloud/cloudfunctions/common/uni-id/config.json 文件中填写自己的 `passwordSecret` 字段 (用于加密密码入库的密钥) 和 `tokenSecret` 字段 (为生成 token 需要的密钥,测试期间跳过本条也可以)
3. 右键 uniCloud目录 运行云服务空间初始化向导,初始化数据库和上传部署云函数(如已创建并绑定云服务空间,则跳过此步)
4. 点击HBuilderX工具栏的运行【Ctrl+r】 -> 运行到浏览器。如果是连接本地云函数调试环境,上一步可以不上传云函数,但数据库仍需初始化。
5. 从启动后的登录页面的底部,进入创建管理员页面(仅允许注册一次管理员账号)
**注意**
- 在 HBuilderX 中运行需在插件市场在安装 [sass 插件](https://ext.dcloud.net.cn/plugin?id=2046)
- 手机端报 `request:fail`,需要去云服务空间的`跨域配置`配置跨域域名,需带端口
- 浏览器联网失败,报 `request:fail`,需要去云服务空间的`跨域配置`配置跨域域名,需带端口。[详见](https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=useinh5)
- 如从未接触过uniCloud,是无法直接上手uniCloud admin的,建议先通读下uniCloud文档的概念介绍和快速上手章节。[详见](https://uniapp.dcloud.net.cn/uniCloud/README)
### 目录结构
......@@ -177,11 +189,11 @@ export default {
##### 管理动态菜单
云后台数据库的 `opendb-admin-menus` 表中管理菜单, 对菜单增删改查。如下图:
左侧导航菜单中,找到`系统管理 -> 菜单管理`,可视化的维护菜单。
![add-menu](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/aa7adb00-152a-11eb-81ea-f115fe74321c.png)
菜单数据存储在云数据库的 `opendb-admin-menus` 表中。该表字段说明如下:
_菜单字段解释:_
_菜单字段解释:_
| 字段 | 类型 | 必填 | 描述 |
| :---------- | :-------- | :--- | :--------------------------------------------------- |
......@@ -197,51 +209,11 @@ _菜单字段解释:_
_添加菜单记录需要注意:_
- 无子菜单,则需 `url` 字段不能为空,该菜单才能在页面显示
- 有子菜单,则需至少一个子菜单的 `url` 字段不能为空,该菜单才能在页面显示
例如,如需增加如下菜单:
```bash
订单管理 # 父菜单
└── 手机 # 子菜单
```
**step 1:**添加一条父菜单记录
菜单的 `parent_id` 字段为空, 即为一级菜单
菜单项分目录菜单和页面菜单。
```json
{
"menu_id": "order",
"name": "订单管理",
"icon": "uni-icons-cart-filled",
"url": "",
"sort": 2,
"parent_id": "",
"permission": [],
"enable": true,
"create_date": "1602662469396"
}
```
- 目录菜单项:非叶子节点,点击后展开子菜单,自身没有 `URL` 。需至少一个子菜单的 `url` 字段不能为空,该菜单才能在页面显示
- 页面菜单项:叶子节点,无子菜单,且 `url` 字段不能为空,点击该菜单项会转到`url`页面。如果 `url` 为空则该菜单无法显示。
**step 2:**添加一条子菜单记录
将子菜单的 `parent_id` 指向父菜单的 `menu_id`即可,孙菜单就是将子菜单的 `menu_id` 当做父菜单
```json
{
"menu_id": "phone",
"name": "手机",
"icon": "uni-icons-phone",
"url": "pages/phone",
"sort": 3,
"parent_id": "order",
"permission": [],
"enable": true,
"create_date": "1602662469492"
}
```
##### 侧边栏样式管理
......@@ -266,11 +238,9 @@ $menu-text-color-actived: #409eff; /* 菜单激活前景色 */
### icon 图标
admin 框架内置了一套 icon 图标,在静态功能演示-图标菜单中,点击图标即可复制图标的 class 定义,或者直接到`common/uni-icons.css`中查看定义,然后以如下方式使用:
admin 框架内置了一套 icon 图标,在`静态功能演示-图标`菜单中,点击图标即可复制图标的 class 定义。
```
<view class="uni-icons-gear"></view>
```
选中样式后,在新建菜单页面的表单中输入样式名称。没有样式的菜单项将没有图标。
当然,你也可以使用三方 icon 库。以使用 `elementUI` 的图标为例,在 `app.vue` 中导入图标库的样式文件:
......@@ -281,11 +251,7 @@ admin 框架内置了一套 icon 图标,在静态功能演示-图标菜单中
</style>
```
在标签上使用图标的 class 名称,即:
```
<view class="el-icon-s-tools"></view>
```
在标签上使用图标的 class 名称即可:``el-icon-s-tools``
### 用户-角色-权限
......@@ -332,10 +298,11 @@ admin 提供了两个内置方法,方便在页面中鉴定登录用户权限
开发页面不局限开发方式:
- 可以新增普通的页面,在前端 callfunction,后台搭配云函数操作
- 可以使用 uni-clientdb,在前端直接操作数据库,后台配置 db schema 进行权限和格式校验
- 可以使用云函数单文件路由,在项目中默认包含了一个[uni-cloud-router](https://uniapp.dcloud.io/uniCloud/uni-cloud-router) 的单文件路由,也可以使用插件市场的其他单文件路由
- 可以使用 clientdb,在前端直接操作数据库,后台配置 db schema 进行权限和格式校验
- 可以使用schema2code生成uniCloud admin页面。这是最为常用、最高效的页面开发模式。[详见](https://uniapp.dcloud.net.cn/uniCloud/schema?id=autocode)
> 注意:在搭配云函数操作,controller 下的文件夹和文件,不要命名相同,例如:app/room 这个写法目前分辨不了 `app` 是文件 `app.js`,还是文件夹 `app`
> 注意:在使用 uni-cloud-router 时,controller 下的文件夹和文件,不要命名相同,例如:app/room 这个写法目前分辨不了 `app` 是文件 `app.js`,还是文件夹 `app`
#### 自己开发页面
......@@ -346,11 +313,10 @@ admin 中开发页面,和 uni-app 开发 vue 页面是一致的。
_使用步骤:_
1.[插件市场](https://ext.dcloud.net.cn/)导入插件
2. 在 HBuilder X 2.9.5 中选择添加插件的项目
3. 覆盖项目的 db_init.json 文件, 点击“确定覆盖”
4. 在 db_init.json 文件上右键,点击“初始化云数据库”
5. 在菜单管理中的添加【待添加菜单】
6. 刷新 admin 即可在菜单栏看到新增的菜单
2. 在 HBuilder X 3.1+ 中选择添加插件的项目
3. 在插件的 db_init.json 文件上右键,点击“初始化云数据库”
4. 在菜单管理中的添加【待添加菜单】
5. 刷新 admin 即可在菜单栏看到新增的菜单
---------------------------------- 分割线 ----------------------------------------
......@@ -376,7 +342,7 @@ _admin 插件的目录结构:_
├── pages # 页面
│ └── your-page # 你的页面
├── pages.json # 插件包含的页面的路由配置
└── %pluginId%-menu.json # 向uniCloud admin左侧菜单注册新菜单的声明文件。pluginId 为你上传插件市场时填的插件id
└── %pluginId%-menu.json # 向uniCloud admin左侧菜单注册新菜单的声明文件。pluginId 为你上传插件市场时填的插件id。uni_module下不需要pluginId,直接就是menu.json
```
**page.json 配置:**
......@@ -389,7 +355,7 @@ _admin 插件的目录结构:_
pluginId 为你上传插件市场时填的插件id(插件市场每个插件都有一个唯一id)。
假使你的插件id为“xxx-yyy”,那么在插件的根目录放置 xxx-yyy-menu.json ,按下文格式配置内容。
假使你的插件id为“xxx-yyy”,那么在插件的根目录放置 xxx-yyy-menu.json ,按下文格式配置内容。(uni_module下不需要pluginId,直接就是menu.json)
```json
[
......@@ -427,7 +393,7 @@ uniCloud admin自带了一个单路由框架,uni-cloud-router,然后自带
为防止和用户工程的文件冲突,插件的页面应该有插件的前缀,比如 pages/xxx-page。自带的数据库schema文件也推荐带上前缀。
以下为已存的 uniCloud admin 插件列表,可以参考:[https://ext.dcloud.net.cn/?cat1=7&cat2=74&orderBy=UpdatedDate](https://ext.dcloud.net.cn/?cat1=7&cat2=74&orderBy=UpdatedDate)
以下为已存的 uniCloud admin 插件列表,可以参考:[https://ext.dcloud.net.cn/?cat1=7&cat2=74&orderBy=UpdatedDate](https://ext.dcloud.net.cn/?cat1=7&cat2=74&orderBy=UpdatedDate)
**插件开发后如何上传插件市场**
......
此差异已折叠。
## 简介
## 简介@intro
云函数是运行在云端的 `JavaScript` 代码,和普通的`Node.js`开发一样,熟悉`Node.js`的开发者可以直接上手。
......@@ -28,11 +28,15 @@ exports.main = async (event, context) => {
let appid = context.APPID // manifest.json中配置的appid
let clientIP = context.CLIENTIP // 客户端ip信息
let clientUA = context.CLIENTUA // 客户端user-agent
let spaceInfo = context.DEVICEID // 客户端标识,新增于HBuilderX 3.1.0,同uni-app客户端getSystemInfo接口获取的deviceId
let spaceInfo = context.SPACEINFO // 当前环境信息 {spaceId:'xxx',provider:'tencent'}
... //其它业务代码
}
```
>在云函数URL化的场景无法获取客户端平台信息,可以在调用依赖客户端平台的接口接口之前(推荐在云函数入口)通过修改context.PLATFORM手动传入客户端平台信息
云函数url化的场景下无法获取`context.OS``context.PLATFORM``context.APPID``context.CLIENTUUID`
>在云函数URL化的场景无法获取客户端平台信息,可以在调用依赖客户端平台的接口接口之前(推荐在云函数入口)通过修改context.PLATFORM手动传入客户端平台信息供其他插件(如:uni-id)使用
例:
......
# uniCloud客户端sdk
uniCloud分为客户端和云端两部分,有些接口名称相同,参数也相近,在此列举客户端sdk内可以使用的接口/属性,避免混淆
## API
客户端API列表
|API |描述 |
|-- |-- |
|uniCloud.callFunction() |客户端调用云函数 [详情](https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=clientcallfunction) |
|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.chooseAndUploadFile() |客户端选择文件并上传 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=chooseanduploadfile) |
|uniCloud.getCurrentUserInfo() |获取当前用户信息 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=client-getcurrentuserinfo) |
|uniCloud.init() |同时使用多个服务空间时初始化额外服务空间 [详情](https://uniapp.dcloud.net.cn/uniCloud/init) |
### 获取当前用户信息@client-getcurrentuserinfo
新增于HBuilderX 3.1.0版本,通过解析客户端token获取用户信息,不会发送网络请求,**注意这个仅仅是客户端接口,不校验token的合法性**
> 需要搭配uni-id使用并要求客户端必须将token存储在storage内的`uni_id_token`内
用法:`uniCloud.getCurrentUserInfo()`
**响应参数**
| 字段 | 类型 | 必填| 说明 |
| --- | --- | --- | --- |
| uid | Number| 是 |当前用户uid |
| role | Array | 是 |用户角色列表 |
| permission| Array | 是 |用户权限列表,admin角色此数组为空|
未能获取用户信息时返回以下结果
```js
{
uid: null,
role: [],
permission: []
}
```
## 属性
### 获取当前uniCloud实例的服务商
用法:`uniCloud.config.provider`
访问此属性会返回`tencent``aliyun`分别代表腾讯云和阿里云
\ No newline at end of file
此差异已折叠。
## 什么是索引
所有数据库都支持索引,索引文件通过额外占用磁盘空间,提供了一个快速查询记录的方案。查询时先查询索引文件,根据索引文件的指示再去查询真实的数据,在数据量较大时有明显的性能优势。
索引有两个用途:
1. 在集合中为查询条件的**字段**建立索引,是保证数据库性能、提升用户体验的重要手段。
2. 索引可以控制字段中各记录的唯一性。比如某字段被设为唯一索引,则这个字段在整个数据记录集合中的值不会有重复。如果是普通唯一索引,则意味着该字段不能为null。如果是稀疏索引,则代表可以为null,但不为null的值不能重复。
如果您的查询操作包含了过滤条件(包含等值测试和范围过滤)或者是排序功能,或者需要唯一性,则要考虑给集合的相关字段添加索引。通常来说需要为以下方法/属性内用到的**字段**添加索引`where、match、orderBy、sort`,还包括clientDB内`getTree``getTreePath``startWith属性`
如果相关字段没有设为索引,当数据表的记录数量变大后,查询会变慢甚至超时报错。这点尤其需要注意。已经有一些开发者遭遇线上故障。开发时没有配索引,因为数据量小而没有性能问题。上线后数据量越来越大,查询越来越慢,直到超时,引发线上事故。
## 添加索引
### uniCloud web控制台添加
1. 进入 [uniCloud 控制台](https://console.cloud.tencent.com/tcb)
2. 切换到【云数据库】标签页,并选择需要添加索引的集合,进入索引管理 tab 页,如下图。
![web控制台添加索引](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/15d24770-5faf-11eb-8d54-21c4ca4ce5d7.jpg)
3. 添加索引。
![添加索引](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/fca53140-1d91-11eb-880a-0db19f4f74bb.jpg)
注意:
- 索引是支持多字段组合的,所以不是简单的设某个字段为索引。而是需要先给索引起一个name,然后在该索引下配置1个或多个字段。
- 索引字段的排序,指查询语句中的orderby的顺序。如果实际查询是需要倒叙,那么索引就设为倒叙,这样查询速度才能变快。
### 在db_init.json内配置集合索引
在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 // 索引是否唯一
}
}]
}
}
```
## 单字段索引
您可以为查询条件对应的字段创建单字段索引,如果该字段是嵌套字段,可以使用"点表示法" 。例如对如下格式的记录中的`color`字段进行索引时,可以用`style.color`表示。
```json
{
"_id": "",
"style": {
"color": ""
}
}
```
在设置单字段索引时,可任意指定索引的排序为升序或降序,数据库总能在对索引字段的排序查询中,进行正确的排序。
## 组合索引
组合索引即一个索引包含多个字段。当查询条件使用的字段包含在索引定义的所有字段或前缀字段里时,会命中索引,优化查询性能。
> 索引前缀即组合索引的字段中定义的前 1 到多个字段,例如对集合 **students** 中 **name**, **age**, **score** 三个字段按顺序定义了组合索引,那么该索引的前缀包含
>
> - **name**
> - **name, age**
>
> 能命中索引的查询字段组合包含
>
> - **name**
> - **name, age**
> - **name, age, score**
>
```json
{
"_id": "1",
"name": "luke",
"age": 26,
"score": 80
}
```
组合索引具有以下特点:
1. **字段顺序决定组合索引效果**
例如定义组合索引分别为 **name, age****age, name** 是不同的。当组合索引为 **name, age** 时,其索引前缀为 **name**, 对字段 **name** 的查询可以命中 **name, age** 索引, 而对字段 **age** 的查询无法命中该索引,因为 **age** 不属于 **name, age** 的前缀(反之字段 **age** 能命中 **age, name** 索引)。
2. **查询字段排序影响命中索引**
组合索引为 **age: 升序, score: 降序**,字段排序对索引命中效果如下:
| **age: 升序, score: 降序** | **age: 降序, score: 升序** | **age: 升序, score: 升序** | **age: 降序, score: 降序** | **score: 升序/降序, age: 升序/降序** |
| -------------------------- | -------------------------- | -------------------------- | -------------------------- | ------------------------------------ |
| 命中 | 命中 | 未命中 | 未命中 | 未命中 |
组合索引为 **age: 升序, score: 升序**,字段排序对索引命中效果如下:
| **age: 升序, score: 升序** | **age: 降序, score: 降序** | **age: 升序, score: 降序** | **age: 降序, score: 升序** | **score: 升序/降序, age: 升序/降序** |
| -------------------------- | -------------------------- | -------------------------- | -------------------------- | ------------------------------------ |
| 命中 | 命中 | 未命中 | 未命中 | 未命中 |
**说明**
- 未进行排序的字段设置正序倒序均可。
- 排序字段内存在索引不存在的情况下不会命中索引,例:组合索引为 **age: 升序, score: 升序**,使用`age、score、name`三个字段进行排序不会使用上述组合索引。
### 地理位置索引
云数据库目前支持建立平面几何的地理位置索引,使用地理位置查询功能时,必须为地理位置数据的字段建立地理位置索引。
例如对含地理位置字段 **point** 的集合建立地理位置索引:
```json
{
"_id": "",
"point": new db.Geo.Point(50, 50)
}
```
![地理位置索引](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/21b31780-5fb0-11eb-bdc1-8bd33eb6adaa.jpg)
## 索引使用注意事项
### 唯一性限制
创建索引时,索引属性选择**唯一**,即可添加唯一性限制。此限制会要求集合中**索引字段对应的值不能重复**
例如,某个集合内建立了索引字段 `foo`,且属性为“唯一”,那么在这个集合内,要求不能存在 `foo` 字段相同的文档。
**注意**
假如**记录中不存在某个字段,则对索引字段来说其值默认为 null**。如果索引有唯一性限制,则不允许存在两个或以上的该字段为空 / 不存在该字段的记录。
针对上述问题,阿里云支持将索引设置为[稀疏索引](uniCloud/db-index.md?id=sparse),腾讯云暂不支持稀疏索引。
### 稀疏索引@sparse
> 仅阿里云支持
稀疏索引适用于需要某个字段唯一,但是这个字段又可能为空的场景。以`uni-id-users`表为例,用户可能是通过邮箱注册、也可能是通过手机号注册,所以需要保证邮箱、手机号唯一且允许为空,这时候就可以分别将邮箱、手机号的索引设置为稀疏索引来处理这种场景。
**配置索引为稀疏索引**
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/daf77fd0-5fb3-11eb-b680-7980c8a877b8.jpg)
### 字段大小限制
- 索引字段的值大小限制**不能超过 1024 字节**
- 添加索引时,如果集合中已有文档索引字段内容超过 1024 字节,添加索引时将报错。
- 已设置索引的字段,如果插入一个文档,文档中该字段内容超过 1024 字节将会报错。
**即不要对大段的文字(例如新闻的内容)设置索引**
> 每个英文字母(不分大小写)占一字节的空间,每个中文汉字占两字节的空间。
### 正则表达式
正则查询无法使用索引提升性能。
慢查询,指云数据库查询较慢,不能及时返回结果。这样的查询会收录在 uniCloud web控制台的慢查询日志栏目中。但收录不是实时的,有一定延时。
开发者应经常查阅自己的慢查询,修复问题,保证业务系统的健康稳定。
在数据库查询超过1秒仍不能返回结果后,阿里云甚至会报错`operation exceeded time limit`
这里介绍如何进行查询优化以避免此类问题。
## 设置合适的索引
请参阅:[数据库索引](uniCloud/db-index.md)
## 大量数据查询优化
如果您的数据量非常大,在设置合适的索引之后仍然会查询超时,您要考虑以下优化方案。
尽量避免使用skip,至少不应该skip比较大的值,因为skip操作Mongo服务端依然会扫描被skip的数据,带skip操作的耗时和skip的数量线性相关。您可以考虑使用排序和范围查询功能来替代直接使用skip。
对于非常大的数据可以分段来查询,即通过一定的条件将一次查询拆分为多次查询操作。
### 带条件的count
如果满足条件的数据特别多,where+count会特别慢,很有可能超时。我们建议不要在大数据量的集合内这样使用count方法。
### 使用skip方法传入较大的值
您应该避免使用where+skip+limit的查询方式来遍历整个集合,因为这种方式随着Skip数量的增长响应时间会越来越慢,还可能会造成请求超时。
下面的代码给出了一个示例。每次查询时都指定查询条件大于上次查询结果中的最后一条记录的_id,
```js
const db = uniCloud.database()
const dbCmd = db.command
module.exports = async function(event,context) {
const {
lastId,
pageSize
} = event
if(pageSize > 100){
throw new Error('单页数据不可超过100条')
}
const res = await db.collection('book').where({
_id: dbCmd.gt(lastId)
})
.limit(pageSize)
.get()
}
```
使用上述写法后您应该使用上一页、下一页、上n页(其中n是一个比较小的数字)、下n页的翻页功能来替换随机翻页。您可以参考百度或者谷歌的搜索结果的分页功能,当结果页数非常多时,不展示共有多少页,仅支持在前10页中支持随机翻页;再往下翻页的过程中,不再支持随机翻页,仅支持向下翻一个较小的页数,这样就可以在已经查询出结果的基础上再使用where+skip(少量)+limit+orderBy的方式来快速查询到结果。
......@@ -6,9 +6,10 @@
简单来说,uniCloud和微信小程序云开发、支付宝小程序云开发一样稳定健壮,但有更多优势:
- 跨平台。不管你在uniCloud里选择了阿里还是腾讯的serverless,均可以跨uni-app的全端使用。从pc到h5,从Android到iOS,以及各家小程序快应用,十几个平台全端支持
- uniCloud提供了`clientDB`神器,减少90%的服务器开发工作量,且保障数据安全。[详见](https://uniapp.dcloud.io/uniCloud/database)
- uniCloud提供了[uni-id](https://uniapp.dcloud.io/uniCloud/uni-id)[uniPay](https://uniapp.dcloud.io/uniCloud/unipay)等重要框架,大幅减少开发者的相应功能开发量。
- uniCloud提供了[uniCloud admin](https://uniapp.dcloud.io/uniCloud/admin),管理端开发工作量大幅减少。
- uniCloud提供了`clientDB`神器,减少90%的服务器开发工作量,且保障数据安全。[详见](/uniCloud/database)
- uniCloud提供了[uni-id](/uniCloud/uni-id)[uniPay](/uniCloud/unipay)等重要框架,大幅减少开发者的相应功能开发量。
- uniCloud提供了[uniCloud admin](/uniCloud/admin),管理端开发工作量大幅减少。
- uniCloud提供了[schema2code](/uniCloud/schema?id=autocode),只需编制数据库schema文件,用户端和管理端的数据列表、分页、搜索、详情查看、修改、删除,全套代码均能自动生成。
- 更易学。uniCloud提供了`JQL`查询语言,比SQL和MongoDB的查询语法更简单易掌握,尤其是联表查询非常简单。[详见](https://uniapp.dcloud.io/uniCloud/database?id=jsquery)
- 更完善的工具链。前端uni-app、云端uniCloud、还有ide端的HBuilderX,互相紧密搭配,打造闭环的优秀开发体验
- 更丰富的生态。插件市场有大量现成的轮子和资源 [详见](https://ext.dcloud.net.cn/?cat1=7&orderBy=TotalDownload)
......@@ -39,7 +40,7 @@
### uniCloud只支持uni-app,怎么开发web界面?
uni-app本来可以开发web界面,详见:[uni-app宽屏适配指南](https://uniapp.dcloud.io/adapt)
uni-app可以开发web界面,详见:[uni-app宽屏适配指南](https://uniapp.dcloud.io/adapt)
如果是需要pc版admin的话,uniCloud提供了[uniCloud admin](https://uniapp.dcloud.io/uniCloud/admin)
......@@ -55,15 +56,39 @@ uniCloud提供了`云函数URL化`,来满足上述需求。[详见](https://un
### 微信云开发支持客户端直接操作数据库,uniCloud支持吗?
uniCloud提供了比微信云开发更优秀的前端操作数据库方案,见:[clientDB](https://uniapp.dcloud.net.cn/uniCloud/database)
### 云开发是nodejs+MongoDB组合,对比php+mysql的传统组合怎么样?
nodejs的性能高于php,MongoDB的性能也优于mysql。
### 云开发是nodejs+改良版MongoDB组合,对比php+mysql的传统组合怎么样?
nodejs的性能也于php,MongoDB的性能也优于mysql。
对于前端而言,MongoDB这种类json的文档数据库更加易用,且有更高的灵活性。
操作MongoDB仍然使用js的方法,而无需学习sql语句。
操作MongoDB仍然使用js的方法。
MongoDB非常灵活,可以对大数据量的表随便增加字段。而mysql的表数据量一旦变大,每增加一个字段,数据库的体积和性能都会造成负面影响。
MongoDB的字段可以嵌套,表达tree型的数据非常方便,扩展起来随心所欲。
对于希望增加数据冗余以提高性能的开发者而言,nosql数据库则是利器。
当然,对于喜欢传统数据库的开发者而言,仍然可以按传统方式设计数据库表结构。
MongoDB的功能要比mysql强大很多。sql太简单的了,一段sql语句其实就是一个字符串,写不了复杂的逻辑。
而MongoDB有非常多的js api,各种聚合运算符,它是可编程的,而不是仅靠一段字符串sql语句来表达。
举个例子,商品数据表中有4个字段:浏览量、收藏量、购买量、评价。需要生成一个近期热门商品列表,4个字段各占25%的权重,加权后排序。这种需求sql是无法直接实现的。而MongoDB里可以一个查询直接返回排序好的结果。
SQL的模糊查询也很弱,like只有前后%,导致很多开发者不得不再使用ElastciSearch这些三方数据库。虽然后期版本的mysql也支持有限正则。但MongoDB的正则查询还是超过开发者预期的强大。
MongoDB虽然强大,但易用性不佳,尤其是聚合运算写起来非常复杂。
uniCloud在MongoDB的基础上改良,进一步提供了`DB Schema``JQL`
对于喜欢传统数据库的开发者而言,仍然可以按传统方式设计数据库表结构。对于希望增加数据冗余以提高性能的开发者而言,nosql数据库则是利器。
`DB Schema`是一个json文件,可以对数据进行描述、约定字段值域、控制操作权限、描述字段之间的关系,让数据库管理更高效,并且大幅降低了服务端的代码开发工作量。[详见](https://uniapp.dcloud.io/uniCloud/schema)
uniCloud提供了`JQL`,它更符合js开发者的习惯,并且极大的降低了联表查询的复杂度,其他方案相比`JQL`都复杂很多。[详见](https://uniapp.dcloud.net.cn/uniCloud/database?id=jsquery)
`JQL`是一套操作uniCloud数据库的方法,它更符合js开发者的习惯,并且极大的降低了学习成本和代码量。
比如联表查询、tree查询,都变的非常简单。像tree查询是以往只有oracle才有的功能。`JQL`文档[详见](https://uniapp.dcloud.net.cn/uniCloud/database?id=jsquery)
曾经DCloud官方也推进过阿里云和腾讯云提供serverless的mysql。但经过对MongoDB的深入研究和改良,DCloud已经放弃了难用的mysql。推荐开发者了解uniCloud的云数据库,用起来更强大和方便。
### 支持websocket吗?
websocket的实时特性导致serverless化比较复杂,目前曲线方案有:
......@@ -92,23 +117,26 @@ websocket的实时特性导致serverless化比较复杂,目前曲线方案有
1. 使用clientDB可以减少遇到冷启动问题的概率
2. 非高频访问的云函数,合并到高频云函数中。有的开发者使用纯单页方式编写云函数,即在一个云函数中通过路由处理实现了整个应用的所有后台逻辑。参考[插件](https://ext.dcloud.net.cn/search?q=%E8%B7%AF%E7%94%B1&cat1=7&orderBy=UpdatedDate)
3. 非高频访问的云函数,可以通过定时任务持续运行它(注意腾讯云可以使用这个方式完全避开冷启动,而阿里云的定时任务最短周期大于资源回收周期)
4. 向service@dcloud.io发邮件,申请预留资源不销毁
### uniCloud访问速度感觉不如传统服务器?@slow
有开发者在一台单机上安装php或java,连接同电脑的mysql。然后与uniCloud比较速度,认为uniCloud偏慢。这里需要澄清如下差异:
抛开冷启动,只看热启动,也有开发者反应unicloud的数据不如传统服务器。其实原因如下:
在一台单机上安装php或java,同时安装数据库,访问速度确实快。
- 原因1. 冷启动。具体分析见上一问题
但在使用云数据库时,即数据库是单独的服务器,和运行代码不在一台服务器上时,本身就会略微造成些延迟。
- 原因2. 代码和数据库不在一台服务器
在一台单机上安装php或java,同时安装数据库,访问速度确实快。但在使用云数据库时,即数据库是单独的服务器,和运行代码不在一台服务器上时,就会略微造成些延迟。但商业应用的数据库肯定都是独立服务器。
如果每个请求都要拦截,校验权限,尤其是要查库校验权限的话,访问速度又会进一步延迟。
- 原因3. 拦截器
后端开发的请求一般都有路由管理框架或拦截器,每个请求都要拦截,校验权限。使用这类框架肯定会增加耗时。
clientDB就是这种情况,因为clientDB内部有权限校验系统,某些权限的验证还需要数据库查询。
所以虽然clientDB的速度慢一些,但实际上开发者在自己写了路由拦截和权限管理的框架后,速度也下降。
所以虽然clientDB的速度慢一些,但实际上开发者在自己写了路由拦截和权限管理的框架后,速度也一样会下降。
从uni-id 3.0起,用户的角色权限缓存在token里,不再查库。clientDB的速度比之前提升了100毫秒左右。如果还未升级,请尽快[升级](https://ext.dcloud.net.cn/plugin?id=2116)。同时注意如果用了uniCloud admin,也要配套升级。如果自己在云函数里编写过相关业务逻辑,请务必阅读升级注意事项。
clientDB也仍然在优化,减少查库校验权限的频次,优化速度。
- 原因4. 数据库索引
查询表的索引要正确配置,需要在where里查询的字段都建议配上索引。
### 发布H5时还得自己找个服务器部署前端网页,可以不用自己再找服务器吗?
......@@ -121,7 +149,9 @@ uniCloud支持[前端网页托管](https://uniapp.dcloud.io/uniCloud/hosting),
### uniCloud云数据库如何实现全文检索
查询数据时可以传入正则表达式进行查询,详情请参考[正则表达式查询](https://uniapp.dcloud.io/uniCloud/cf-database?id=regexp)
uniCloud的云数据库本身就是文档型数据库,可以全文检索,无需额外配置ElastciSearch等三方数据库。
查询数据时可以传入正则表达式。相比sql的like只有前后的%,正则表达式要强大的多。详情请参考[正则表达式查询](https://uniapp.dcloud.io/uniCloud/cf-database?id=regexp)
### uniCloud内如何使用formdata
......@@ -154,15 +184,25 @@ uniCloud.httpclient.request('https://example.com',{
### 如何控制云函数数量?云函数是否可以按多级目录整理@merge-functions
其实不需要控制数量,实际开发中不会突破限制。
不需要控制数量,实际开发中不会突破限制。
因为实际开发中会使用框架而不是真的一个一个开发云函数。
1. 使用[clientDB](https://uniapp.dcloud.net.cn/uniCloud/clientdb)。这种方式是在前端直接操作数据库,此时一个云函数都不需要写。开发效率远超传统开发模式。包括它配套的action云函数是不占用云函数数量的。
2. 使用[uni-cloud-router单路由云函数框架](https://uniapp.dcloud.net.cn/uniCloud/uni-cloud-router),这种方式只有一个云函数,所有接口都是这个云函数的不同参数,它有统一的路由管理。
因为大多数项目,会使用clientDB和单路由云函数框架。
以免费空间的48个云函数举例,一般情况下:
- 后台管理系统使用[uniCloud admin](https://uniapp.dcloud.net.cn/uniCloud/admin),会自带一个uni-admin的云函数;
- 前端项目,会有一个[uni-id](https://uniapp.dcloud.net.cn/uniCloud/uni-id)配套的user-center云函数。如果和uniCloud admin复用一个服务空间,此云函数也不需要;
- 如果有热搜词统计跑批,[uni-search](https://ext.dcloud.net.cn/plugin?id=3851)配套一个云函数uni-analyse-searchhot;
上述几个是官方推荐的几个常用框架所带的云函数,然后开发者自己的代码里,大多数业务使用clientDB开发,不写云函数,或者写了配套的action云函数也不占用云函数数量;如果还需要自己写一些云函数,再加上uni-cloud-router,用这个单路由云函数搞定剩余需求;另外如果有跑批数据的需求可以再来一个云函数。所以无论如何48个云函数都占不满。
uniCloud的每个云函数是一个独立进程,不存在云函数级别的多级目录概念。
每个云函数下可以有子目录,但它们都属于这个云函数的一部分,而不是另一个云函数。
当然也可以在一个云函数下实现单路由云函数开发框架,插件市场有很多类似框架:[详见](https://ext.dcloud.net.cn/search?q=%E8%B7%AF%E7%94%B1&cat1=7&orderBy=TotalDownload)
单路由云函数框架不止是官方提供的uni-cloud-router,插件市场有很多类似框架:[详见](https://ext.dcloud.net.cn/search?q=%E8%B7%AF%E7%94%B1&cat1=7&orderBy=TotalDownload)
### 海外用户访问比较慢怎么办
......@@ -225,3 +265,13 @@ exports.main = async function(event){
### 使用腾讯云报未登录Cloudbase
腾讯云会在本地storage存储一些信息,请不要在应用使用过程中使用clearStorage等接口直接删除storage。
### 阿里云前端网页托管域名报错指引@ali-hosting-domain
1. 错误信息:`该域名已经被添加过,不能重复添加`
前端网页托管会和阿里云上其他的CDN业务(包括但不限于CDN)冲突,如需绑定到前端网页托管请先将此域名与其他业务解除关联。
2. 错误信息:`The root domain of your domain is reserved by another account`
当前域名有在阿里云开通全站加速相关业务(可能配置了泛域名加速),与前端网页托管冲突。可以考虑使用三级域名或去除泛域名加速改为单独配置需要加速的域名。
......@@ -175,10 +175,6 @@ data很简单,就是存放的数据记录(record)。
还有“组合索引”的概念,可以把多个字段组合成一个“组合索引”。例如一个文章点赞记录明细表,设置文章id和用户id为组合索引,且将此组合索引设为唯一型索引,就可以限制同一用户对一篇文章多次点赞。
**稀疏索引**
稀疏索引适用于需要某个字段唯一,但是这个字段又可能为空的场景。以`uni-id-users`表为例,用户可能是通过邮箱注册、也可能是通过手机号注册,所以需要保证邮箱、手机号唯一且允许为空,这时候就可以分别将邮箱、手机号的索引设置为稀疏索引来处理这种场景。
**在web控制台添加上述索引**
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/fca53140-1d91-11eb-880a-0db19f4f74bb.jpg)
......@@ -211,6 +207,10 @@ data很简单,就是存放的数据记录(record)。
- 如果已经设置某字段为唯一索引,在新增和修改记录时如果该字段的值之前在其他记录已存在,会失败。
- 假如记录中不存在某个字段,则对索引字段来说其值默认为 null,如果该索引字段设为唯一型索引,则不允许存在两个或以上的该字段为null或不存在该字段的记录。
#### 稀疏索引
[文档已移至](uniCloud/db-index.md?id=sparse)
### 数据表格式定义@dbschema
`DB Schema`是集合的表结构描述。描述集合有哪些字段、值域类型是什么、是否必填、数据操作权限等很多内容。
......@@ -304,7 +304,8 @@ uniCloud数据库提供了多种数据导入导出和备份方案。
"Name": "index", // 索引字段
"Direction": "1" // 索引方向,1:ASC-升序,-1:DESC-降序,2dsphere:地理位置
}],
"MgoIsUnique": false // 索引是否唯一
"MgoIsUnique": false, // 索引是否唯一
"MgoIsSparse": false // 是否为稀疏索引,请参考 https://uniapp.dcloud.net.cn/uniCloud/db-index.md?id=sparse
}
}],
"schema": {
......@@ -355,8 +356,6 @@ uniCloud数据库提供了多种数据导入导出和备份方案。
- 如果表名与opendb中任意表名相同,web控制台导出时将不会带上schema和index。
- web控制台导出时默认不包括`_id`字段,在导入时,数据库插入新记录时会自动补`_id`字段。如果需要指定`_id`,需要手工补足数据。
### 数据库回档备份和恢复@backup
**此功能暂时只有腾讯云支持**
......@@ -418,3 +417,41 @@ uniCloud提供的`db_init.json`主要是为了对数据库进行初始化,并
{"a":1}
{"a":2}
```
> 如果是自己拼接的json格式数据请注意:如果存在集合A关联集合B的字段的场景需要保证关联字段在A、B内是一致的(特别需要注意的是各种与_id关联的字段)
例:
**正确示例**
```js
// 这里为了方便看数据进行了格式化,实际导入所需的json文件是每行一条记录
// article集合
{
"user_id": {
$oid: "601cf1dbf194b200018ed8ec"
}
}
// user集合
{
"_id": {
$oid: "601cf1dbf194b200018ed8ec"
}
}
```
**错误示例**
```js
// 这里为了方便看数据进行了格式化,实际导入所需的json文件是每行一条记录
// article集合
{
"user_id": "601cf1dbf194b200018ed8ec"
}
// user集合
{
"_id": {
$oid: "601cf1dbf194b200018ed8ec"
}
}
```
\ No newline at end of file
......@@ -214,6 +214,10 @@ uni-app项目根据路由模式不同需要做不同的配置
+ 腾讯云配置重定向规则将404错误码重定向至`index.html`
+ 阿里云配置错误文档为`index.html`
手动部署uni-app项目时需要注意将文件部署在配置的h5基础路径下。**HBuilderX一键部署时会自动按照manifest.json内配置的基础路径进行部署**
如果部署多个项目到一个服务空间可以使用不同的基础路径来区分,需要注意的是这多个项目中只有一个项目可以使用history模式
## 腾讯云计费详细说明
|套餐名 |前端网页部署增值包1|前端网页部署增值包2|前端网页部署增值包3|
......
......@@ -14,6 +14,7 @@
**使用限制**
- 腾讯云免费服务空间最多只支持配置10个云函数URL化地址
- 阿里云暂不支持修改响应头中的content-disposition,即无法返回html并在浏览器中展示,只可以触发下载
## 操作步骤
......@@ -112,7 +113,7 @@ $ curl https://${云函数Url化域名}/${path}
```
使用POST请求`https://${云函数Url化域名}/${functionPath}`,云函数接收到的`event`为请求发送的数据,**uni.request默认content-type为application/json**
使用POST请求`https://${spaceId}.service.tcloudbase.com/${functionPath}`,云函数接收到的`event.body`为请求发送的数据,**uni.request默认content-type为application/json**
```js
// 以uni.request为例
......@@ -129,20 +130,16 @@ uni.request({
})
// 云函数收到的event为, 注意如果直接return此格式数据可能会被作为集成响应处理,参考下面的集成响应文档
```
```js
{
path: '/',
httpMethod: 'GET',
httpMethod: 'POST',
headers: {
...
"content-type": 'application/json'
},
queryStringParameters: {a: "1", b: "2"},
requestContext: {云开发相关信息},
isBase64Encoded: false,
body: '{"a":1,"b":2}',
body: '{"a":1,"b":2}', // 注意此处可能是base64,需要根据isBase64Encoded判断
}
```
......@@ -241,6 +238,8 @@ content-length: 13
`content-type`设置为`text/html`,即可在`body`中返回 HTML,会被浏览器自动解析:
**阿里云目前无法返回html并在浏览器中展示,只可以触发下载**
```js
exports.main = function() {
return {
......
掌握uniCloud,不需要学习nodejs。
只需熟悉js即可,然后阅读uniCloud的文档,就像学习一个js框架。
视频教程:
- [网易云课堂unicloud入门到精通](https://study.163.com/course/introduction.htm?courseId=1209978085#/courseDetail?tab=1)
- [B站uniCloud视频](https://search.bilibili.com/all?keyword=unicloud)
......
此差异已折叠。
......@@ -92,7 +92,8 @@ HBuilderX 3.0之前版本目录结构如下:
- 如果未进行实名认证,会跳转至实名认证页面进行实名认证,等待实名认证审核之后可以开通服务空间。若腾讯云实名认证提示身份证下已创建过多账户,则需要在腾讯云官网注销不用的账户。
- 创建服务空间可能需要几十秒的时间,可以在web控制台查看是否创建完成。
- 一个应用,可以在[dev.dcloud.net.cn](https://dev.dcloud.net.cn)设置协作者(选择应用->设置项目成员),实现多人共同使用一个云服务空间。(需 HBuilderX 2.5.9+)需要注意的是目前协作者不可通过web控制台访问服务空间。
- 一个应用,可以在[dev.dcloud.net.cn](https://dev.dcloud.net.cn)设置协作者(选择应用->设置项目成员),实现多人共同使用一个云服务空间。(需 HBuilderX 2.5.9+)。协作者可以在HBuilderX和web控制台中操作被授权的服务空间,除了删除服务空间,其他功能均可正常操作。
- 多个项目可以复用一个服务空间,比如一个应用的用户端和管理端,在HBuilderX里可以创建成2个项目,但2个项目的服务空间可以指向一个,或者干脆把其中一个项目的服务空间绑定到另一个项目上,[详见](https://ask.dcloud.net.cn/article/37949)
## 创建云函数
......@@ -452,7 +453,7 @@ uniCloud支持云函数,但其实大多数场景下并不需要写云函数,
H5前端js访问云函数,涉及跨域问题,导致前端js无法连接云函数服务器。处理方式如下:。
- 运行到H5端时,使用HBuilderX内置浏览器,可以忽略跨域问题(mac版需2.5.10+)。
- 发行到H5端时,需要在uniCloud后台操作,绑定安全域名,否则会因为跨域问题而无法访问。(在`cloudfunctions`目录右键可打开uniCloud后台)
- 发行到H5端时,需要在uniCloud后台操作,绑定安全域名(在部署云函数的服务空间配置部署h5的域名作为安全域名),否则会因为跨域问题而无法访问。(在`cloudfunctions`目录右键可打开uniCloud后台)
> 注意跨域配置需要带上端口信息。例如:前端页面运行于:www.xxx.com:5001,跨域配置内配置:www.xxx.com不会对此页面生效,需要配置为:
......@@ -519,6 +520,7 @@ web控制台网址:[https://unicloud.dcloud.net.cn](https://unicloud.dcloud.ne
}
}
```
注:时间戳无需如此复杂。时间戳只需直接输入不加引号的数字即可。
#### 添加地理位置点@editdb-geopoint
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -2,6 +2,8 @@
> 基于 koa 风格的 uniCloud 云函数路由库,同时支持 uniCloud 客户端及 URL 化访问
源码仓库:[https://gitee.com/dcloud/uni-cloud-router](https://gitee.com/dcloud/uni-cloud-router)
## 介绍
### 目录结构
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -127,7 +127,7 @@ uni.login({
//参考`univerifyStyle 数据结构`
},
success(res){ // 登录成功
console.log(res.authResult); // {openid:'deviceIDlength+deviceID+gyuid',access_token:'接口返回的 token'}
console.log(res.authResult); // {openid:'登录授权唯一标识',access_token:'接口返回的 token'}
},
fail(res){ // 登录失败
console.log(res.errCode)
......@@ -151,11 +151,9 @@ univerifyStyle 数据结构:
},
"phoneNum": {
"color": "#000000", // 手机号文字颜色 默认值:#000000
"fontSize": "18" // 手机号字体大小 默认值:18
},
"slogan": {
"color": "#8a8b90", // slogan 字体颜色 默认值:#8a8b90
"fontSize": "12" // slogan 字体大小 默认值:12
},
"authButton": {
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
......@@ -179,7 +177,6 @@ univerifyStyle 数据结构:
"termsColor": "#1d4788", // 协议文字颜色 默认值: #1d4788
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"fontSize": "12", // 字体大小 默认值:12,
"privacyItems": [
// 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
{
......
......@@ -71,9 +71,13 @@ Vue 组件编译到小程序平台的时候会编译为对应平台的组件,
```js
export default {
props: ['data'],
data(){ return { } },
options: {
multipleSlots: false,// 在微信小程序中关闭当前组件的多slot支持,默认启用
virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现
// 微信小程序中 options 选项
multipleSlots: true, // 在组件定义时的选项中启动多slot支持,默认启用
styleIsolation: "isolated", // 启动样式隔离。当使用页面自定义组件,希望父组件影响子组件样式时可能需要配置。具体配置选项参见:微信小程序自定义组件的样式
addGlobalClass: true, // 表示页面样式将影响到自定义组件,但自定义组件中指定的样式不会影响页面。这个选项等价于设置 styleIsolation: apply-shared
virtualHost: true, // 将自定义节点设置成虚拟的,更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定
}
}
```
......
此差异已折叠。
......@@ -731,7 +731,7 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
你也可以用 v-for 来遍历一个对象的 `property`
- 第一个参数 `value` 是被迭代的数组元素的别名
- 第一个参数 `value` 是被迭代的对象元素的属性值
- 第二个参数为 `property` 名称 (也就是键名)。
- 第三个参数作为索引。
......
......@@ -12,5 +12,5 @@
"message": "chore(release): publish %s"
}
},
"version": "2.0.0-30420201231001"
"version": "2.0.0-31220210205002"
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册