提交 ed37e19d 编写于 作者: D DCloud_LXH

feat: 迁移 uniCloud、uni-app-x 文档

上级 d2838ec5
......@@ -37,11 +37,6 @@ export const navbar = [
type: 'link',
link: '/api/'
},
{
text: 'UTS',
type: 'link',
link: '/uni-app-x/uts/'
},
{
text: '插件',
type: 'link',
......@@ -52,6 +47,11 @@ export const navbar = [
type: 'link',
link: '/worktile/'
},
{
text: 'UTS',
type: 'link',
link: 'https://doc.dcloud.net.cn/uni-app-x/uts/'
},
{
text: '其他规范',
type: 'links',
......@@ -134,64 +134,17 @@ export const navbar = [
},
{
text: 'uni-app x',
link: '/uni-app-x/',
items: [
{
text: '介绍',
type: 'link',
link: '/uni-app-x/'
},
{
text: '编译器',
type: 'link',
link: '/uni-app-x/compiler/'
},
{
text: 'UTS',
type: 'link',
link: '/uni-app-x/uts/'
},
{
text: '全局文件',
type: 'link',
link: '/uni-app-x/collocation/pagesjson'
},
{
text: '组件',
type: 'link',
link: '/uni-app-x/component/'
},
{
text: 'API',
type: 'link',
link: '/uni-app-x/api/'
},
{
text: 'CSS',
type: 'link',
link: '/uni-app-x/css/'
},
{
text: 'DOM',
type: 'link',
link: '/uni-app-x/dom/'
},
{
text: '插件',
type: 'link',
link: '/uni-app-x/plugin/'
},
{
text: '工程化',
type: 'link',
link: '/uni-app-x/worktile/'
}
]
link: 'https://doc.dcloud.net.cn/uni-app-x/',
type: "link",
target: '_blank',
needOutbound: false
},
{
text: 'uniCloud',
type: 'link',
link: '/uniCloud/'
link: 'https://doc.dcloud.net.cn/uniCloud/',
type: "link",
target: '_blank',
needOutbound: false
},
{
text: 'HBuilder',
......
......@@ -70,10 +70,6 @@ const routerMap = {
'/nvue-api': '/tutorial/nvue-api.html',
'/nvue-css': '/tutorial/nvue-css.html',
'/uniCloud/database': '/uniCloud/clientdb.html',
'/uniCloud/uni-clientDB': '/uniCloud/clientdb.html',
'/uniCloud/uni-data-picker': '/component/uniui/uni-data-picker.html',
'/uniCloud/uni-push/introduction.html': '/unipush-v2.html',
'/plugin/publish#pages-init': '/plugin/uni_modules.html#pages-init',
'/tutorial/build/uni-app-publish-mp-weixin': '/tutorial/build/publish-mp-weixin-cli.html',
......@@ -93,14 +89,9 @@ const routerMap = {
'/m3w': '/uniCloud/uni-portal.html',
'/tutorial/syntax-uts': '/uni-app-x/uts/',
'/uniCloud/uni-id-summary': '/uniCloud/uni-id/summary.html',
'/uniCloud/uni-id-pages': '/uniCloud/uni-id/redirect.html',
'/uniCloud/uni-id-common': '/uniCloud/uni-id/cloud-common.html',
'/uniCloud/uni-id': '/uniCloud/uni-id/old.html',
'/uniCloud/': 'https://doc.dcloud.net.cn/uniCloud/',
'/uts/': '/uni-app-x/uts/',
'/uni-app-x/ext': '/uni-app-x/api/ext.html',
'/uni-app-x/pagesjson': '/uni-app-x/collocation/pagesjson.html',
'/uni-app-x/manifest': '/uni-app-x/collocation/manifest.html'
'/uni-app-x/': 'https://doc.dcloud.net.cn/uni-app-x/'
}
export default ({ fullPath, path, hash }) => {
......
......@@ -4,14 +4,14 @@ export default {
text: 'uni-app',
type: 'algolia',
},
{
/* {
text: 'uni-app x',
type: 'algolia',
},
{
text: 'uniCloud',
type: 'algolia',
},
}, */
{
text: '问答社区',
tag: 'ask',
......
......@@ -3,7 +3,7 @@ import uniCloud from './uniCloud';
export default {
"/": uniapp,
"/uni-app-x/": uniapp,
'/uniCloud/': uniCloud,
// "/uni-app-x/": uniapp,
// '/uniCloud/': uniCloud,
weChatOfficialAccountImg: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/weixin.jpg'
}
......@@ -16,8 +16,6 @@ function simplifySlugText(text) {
// 顺序有要求,会影响 for 循环匹配侧边栏
const tabs = [
'/uni-app-x/compiler/', '/uni-app-x/dom/', '/uni-app-x/uts/', '/uni-app-x/collocation/', '/uni-app-x/plugin/', '/uni-app-x/worktile/', '/uni-app-x/component/', '/uni-app-x/api/', '/uni-app-x/css/', '/uni-app-x/',
'/uniCloud/',
'/plugin/', '/worktile/', '/tutorial/', '/collocation/', '/component/', '/api/', '/',
]
......
......@@ -25,11 +25,11 @@
* [微信小程序互动广告](uni-ad/ad-interactive.md)
* [广告错误码](uni-ad/ad-error-code.md)
* [uni-ad管理后台更新说明](uni-ad/release.md)
* [统一发行页面](/uniCloud/uni-portal.md)
* [前端网页托管](uniCloud/hosting.md)
* [App升级中心](uniCloud/upgrade-center.md)
* [统一发行页面](https://doc.dcloud.net.cn/uniCloud/uni-portal.html)
* [前端网页托管](https://doc.dcloud.net.cn/uniCloud/hosting.html)
* [App升级中心](https://doc.dcloud.net.cn/uniCloud/upgrade-center.html)
* [uni一键登录](univerify.md)
* [uni实人认证](uniCloud/frv/intro.md)
* [uni实人认证](https://doc.dcloud.net.cn/uniCloud/frv/intro.html)
* [uni-push统一推送](unipush.md)
* [uni-push1.0](unipush-v1.md)
* [uni-push2.0](unipush-v2.md)
......@@ -38,7 +38,7 @@
* [uni-app客户端api](https://uniapp.dcloud.net.cn/api/plugins/push.html)
* [uni-app x客户端api](https://uniapp.dcloud.net.cn/uni-app-x/api/push.html)
* [服务端api](https://uniapp.dcloud.net.cn/uniCloud/uni-cloud-push/api.html)
* [uni-push2.0、uni-id、uni统计的组合](uniCloud/uni-cloud-push/mate.md)
* [uni-push2.0、uni-id、uni统计的组合](https://doc.dcloud.net.cn/uniCloud/uni-cloud-push/mate.html)
* [uni统计](uni-stat.md)
* [uni统计2.0](uni-stat-v2.md)
* [uni统计1.0](uni-stat-v1.md)`
......
实人认证提供核验终端操作者的真实身份,包含活体检测和人脸对比等生物识别技术,可快速校验自然人的真实身份。
App平台端详细文档需另见:[业务介绍](/uniCloud/frv/intro.md)[开发指南](/uniCloud/frv/dev.md)
App平台端详细文档需另见:[业务介绍](https://doc.dcloud.net.cn/uniCloud/frv/intro.md)[开发指南](https://doc.dcloud.net.cn/uniCloud/frv/dev.html)
微信小程序端业务开发流程,请参考[微信人脸核身接口能力](https://developers.weixin.qq.com/community/business/doc/000442d352c1202bd498ecb105c00d)
......@@ -8,7 +8,7 @@ App平台端详细文档需另见:[业务介绍](/uniCloud/frv/intro.md)、[
uni.getFacialRecognitionMetaInfo是客户端API,获取实人认证设备信息,用于uniCloud云函数[getCertifyId](https://uniapp.dcloud.net.cn/uniCloud/frv/dev.html#get-certify-id)获取certifyId。
App端API规范参考:[详情](/uniCloud/frv/dev.md#get-meta-info)
App端API规范参考:[详情](https://doc.dcloud.net.cn/uniCloud/frv/dev.html#get-meta-info)
**平台说明**
......@@ -21,7 +21,7 @@ App端API规范参考:[详情](/uniCloud/frv/dev.md#get-meta-info)
uni.startFacialRecognitionVerify是客户端API,在App端打开刷脸认证界面。
App端API规范参考:[详情](/uniCloud/frv/dev.md#start-frv)
App端API规范参考:[详情](https://doc.dcloud.net.cn/uniCloud/frv/dev.html#start-frv)
**平台说明**
......
......@@ -3,7 +3,7 @@
uni.login是一个客户端API,统一封装了各个平台的各种常见的登录方式,包括App手机号一键登陆、三方登录(微信、微博、QQ、Apple、google、facebook)、各家小程序内置登录。
除了前端API,DCloud还提供了[uni-id](/uniCloud/uni-id/summary.md),这是一个云端一体的、完整的、账户开源框架。不仅包括客户端API,还包括前端页面、服务器代码、管理后台等所有与登录账户有关的服务,包括短信验证码、密码加密存储、忘记密码、头像更新等所有常见账户相关功能。
除了前端API,DCloud还提供了[uni-id](https://doc.dcloud.net.cn/uniCloud/uni-id/summary.html),这是一个云端一体的、完整的、账户开源框架。不仅包括客户端API,还包括前端页面、服务器代码、管理后台等所有与登录账户有关的服务,包括短信验证码、密码加密存储、忘记密码、头像更新等所有常见账户相关功能。
**平台差异说明**
......@@ -32,7 +32,7 @@ uni.login是一个客户端API,统一封装了各个平台的各种常见的
* [京东小程序登录](https://mp-docs.jd.com/api/openInterface/login.html)
#### web平台支持的登录方式
Web平台常见的登录包括用户名密码、短信验证码、pc端微信扫描、微信公众号登录。这些没有封装在 uni.login API中,但都封装在了uni-id中。请另行参考[uni-id](/uniCloud/uni-id/summary.md)
Web平台常见的登录包括用户名密码、短信验证码、pc端微信扫描、微信公众号登录。这些没有封装在 uni.login API中,但都封装在了uni-id中。请另行参考[uni-id](https://doc.dcloud.net.cn/uniCloud/uni-id/summary.html)
如不使用uni-id,微信内嵌浏览器运行H5版时,可通过js sdk实现微信登录,需要引入一个单独的js,[详见](https://ask.dcloud.net.cn/article/35380)
......
......@@ -132,4 +132,4 @@ QQ小程序订阅消息文档:[https://q.qq.com/wiki/develop/miniprogram/frame
华为快应用推送文档:[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 [详情参考](/uniCloud/uni-cloud-push/api)
## 服务端API [详情参考](https://doc.dcloud.net.cn/uniCloud/uni-cloud-push/api)
......@@ -2,7 +2,7 @@
生物认证,包含手机的指纹识别、faceid两部分。即通过人体身体特征来进行身份认证识别。
如需要专业的活体检测、人脸识别、金融级实人认证,需另见文档[uni实人认证](/uniCloud/frv/intro.md)
如需要专业的活体检测、人脸识别、金融级实人认证,需另见文档[uni实人认证](https://doc.dcloud.net.cn/uniCloud/frv/intro.html)
### uni.startSoterAuthentication(OBJECT)
......@@ -35,7 +35,7 @@
注意:
- App端指纹识别,Android平台从Android6.0起才提供了官方API,uni-app也是从Android6起支持。对于更低版本的安卓,某些rom私有的指纹识别API,uni-app并不支持。
- App端人脸识别,iOS平台使用自带的faceID。Android平台需另行使用uni实人认证,另见[https://uniapp.dcloud.net.cn/uniCloud/frv/intro.html](/uniCloud/frv/intro.md)
- App端人脸识别,iOS平台使用自带的faceID。Android平台需另行使用uni实人认证,另见[https://uniapp.dcloud.net.cn/uniCloud/frv/intro.html](https://doc.dcloud.net.cn/uniCloud/frv/intro.html)
**OBJECT.success返回值说明**
......
### uniCloud
完整uniCloud客户端api列表请参考:[uniCloud客户端sdk](uniCloud/client-sdk.md)
完整uniCloud客户端api列表请参考:[uniCloud客户端sdk](https://doc.dcloud.net.cn/uniCloud/client-sdk.html)
......@@ -18,7 +18,7 @@
|[leftWindow](/collocation/pages?id=leftwindow)|Object|否|大屏左侧窗口|H5|
|[topWindow](/collocation/pages?id=topwindow)|Object|否|大屏顶部窗口|H5|
|[rightWindow](/collocation/pages?id=rightwindow)|Object|否|大屏右侧窗口|H5|
|[uniIdRouter](/uniCloud/uni-id/summary.md#uni-id-router)|Object|否|自动跳转相关配置,新增于HBuilderX 3.5.0|uni-app x 不支持|
|[uniIdRouter](https://doc.dcloud.net.cn/uniCloud/uni-id/summary.html#uni-id-router)|Object|否|自动跳转相关配置,新增于HBuilderX 3.5.0|uni-app x 不支持|
|entryPagePath|String|否|默认启动首页,新增于HBuilderX 3.7.0|微信小程序、支付宝小程序|
以下是一个包含了所有配置选项的 `pages.json`
......@@ -977,7 +977,7 @@ h5 平台下拉刷新动画,只有 circle 类型。
- 考虑到编译速度,直接在`pages.json`内修改`easycom`不会触发重新编译,需要改动页面内容触发。
- `easycom`只处理vue组件,不处理小程序专用组件(如微信的wxml格式组件)。不处理后缀为.nvue的组件。因为nvue页面引入的组件也是.vue组件。可以参考uni ui,使用vue后缀,同时兼容nvue页面。
- `nvue`页面里引用`.vue`后缀的组件,会按照nvue方式使用原生渲染,其中不支持的css会被忽略掉。这种情况同样支持`easycom`
- `vue``uvue` 组件优先级,[详见](/uni-app-x/component/README.md#priority)
- `vue``uvue` 组件优先级,[详见](https://doc.dcloud.net.cn/uni-app-x/component/README.html#priority)
### Bug & Tips@easycom_tips
+ HBuilderX 3.96 版本以下`uni-app x`项目,当页面文件名与`easycom`的组件名一样时,会渲染异常,可以通过调整页面文件名规避该Bug。
......
......@@ -257,7 +257,7 @@ uni-app为开发者提供了一系列基础组件,类似HTML里的基础标签
|组件名|说明|
|:-|:-|
|[unicloud-db组件](/uniCloud/unicloud-db)|uniCloud数据库访问和操作组件|
|[unicloud-db组件](https://doc.dcloud.net.cn/uniCloud/unicloud-db)|uniCloud数据库访问和操作组件|
**各平台专有组件**
......@@ -311,7 +311,7 @@ uni-app支持的组件分为vue组件和小程序自定义组件。
传统vue组件,需要安装、引用、注册,三个步骤后才能使用组件。`easycom`将其精简为一步。
只要组件安装在项目的components目录下或`uni_modules`目录下,并符合`components/组件名称/组件名称.(vue|uvue)`目录结构(注意:当同时存在vue和uvue时,uni-app 项目优先使用 vue 文件,而uni-app x 项目优先使用 uvue 文件,[详情](/uni-app-x/component/#%E5%A6%82%E4%BD%95%E5%BC%80%E5%8F%91%E5%90%8C%E6%97%B6%E5%85%BC%E5%AE%B9-uni-app-x-%E5%92%8C-uni-app-%E7%9A%84%E7%BB%84%E4%BB%B6))。就可以不用引用、注册,直接在页面中使用。
只要组件安装在项目的components目录下或`uni_modules`目录下,并符合`components/组件名称/组件名称.(vue|uvue)`目录结构(注意:当同时存在vue和uvue时,uni-app 项目优先使用 vue 文件,而uni-app x 项目优先使用 uvue 文件,[详情](https://doc.dcloud.net.cn/uni-app-x/component/#%E5%A6%82%E4%BD%95%E5%BC%80%E5%8F%91%E5%90%8C%E6%97%B6%E5%85%BC%E5%AE%B9-uni-app-x-%E5%92%8C-uni-app-%E7%9A%84%E7%BB%84%E4%BB%B6))。就可以不用引用、注册,直接在页面中使用。
比如前述举例的[uni-rate组件](https://ext.dcloud.net.cn/plugin?id=33),它导入到uni-app项目后,存放在了目录/components/uni-rate/uni-rate.vue
......@@ -385,7 +385,7 @@ uni-app的基础组件中,有一个特殊基础组件是:`<unicloud-db>`组
它可以在前端直接获取和操作uniCloud的云端数据库。
相关文档详见:[unicloud-db组件](/uniCloud/unicloud-db)
相关文档详见:[unicloud-db组件](https://doc.dcloud.net.cn/uniCloud/unicloud-db)
除了内置的数据库组件,在uni-ui扩展库里还有uniCloud的文件选择和上传组件,参考:[uni-file-picker](https://ext.dcloud.net.cn/plugin?id=4079)
......
......@@ -56,7 +56,7 @@
* [微信小程序](component/ad-weixin.md)
* [微信小程序格子广告](component/ad-grid.md)
* [广告错误码](component/ad-error-code.md)
* [uniCloud-db云数据库](/uniCloud/unicloud-db.md)
* [uniCloud-db云数据库](https://doc.dcloud.net.cn/uniCloud/unicloud-db.html)
* [页面属性配置节点](component/page-meta.md)
* [page-meta](component/page-meta.md)
* [navigation-bar](component/navigation-bar.md)
......
......@@ -34,7 +34,7 @@ code|message|
4. 激励视频因为有奖励,很容易招惹灰黑产,为防止被刷,推荐使用:
- 1) 开通激励视频的服务器回调 [详情](ad-rewarded-video.md#callback)
- 2) 不使用短信验证码等不安全登录手段,改为[App一键登陆](../univerify.md)、uni金融级实人认证(含活体检测)等更安全的身份校验
- 3) 使用uni云端一体安全网络,防止伪造客户端 [详情](../uniCloud/secure-network.md)
- 3) 使用uni云端一体安全网络,防止伪造客户端 [详情](https://uniapp.dcloud.net.cn/uniCloud/secure-network.md)
#### 不治本的绕过型方案
......
......@@ -371,7 +371,7 @@ mixin是vue的技术,不熟悉的可以点此了解[vue官网的mixin文档](h
|属性名 | 类型 | 默认值 | 说明|
|:-: | :-: | :-: | :-: |
|localdata |Array | |本地数据,[详情](https://uniapp.dcloud.net.cn/component/datacom)|
|spaceInfo |Object | |服务空间信息,新增于`HBuilderX 3.2.11`。同uniCloud.init参数,参考:[uniCloud.init](uniCloud/init.md?id=init-unicloud)|
|spaceInfo |Object | |服务空间信息,新增于`HBuilderX 3.2.11`。同uniCloud.init参数,参考:[uniCloud.init](https://doc.dcloud.net.cn/uniCloud/init.html?id=init-unicloud)|
|collection |String | |表名。支持输入多个表名,用 `,` 分割|
|field |String | |查询字段,多个字段用 `,` 分割|
|where |String | |查询条件,内容较多,另见jql文档:[详情](https://uniapp.dcloud.net.cn/uniCloud/uni-clientDB?id=jsquery)|
......@@ -388,7 +388,7 @@ mixin是vue的技术,不熟悉的可以点此了解[vue官网的mixin文档](h
|gettree |Boolean | false |是否查询树状数据,默认 `false`|
|startwith |String | '' |`gettree`的第一层级条件,此初始条件可以省略,不传startWith时默认从最顶级开始查询|
|limitlevel |Number | 10 |`gettree`查询返回的树的最大层级。超过设定层级的节点不会返回。默认10级,最大15,最小1|
|foreign-key |String | '' |手动指定使用的关联关系,HBuilderX 3.1.10+ [详情](/uniCloud/clientdb?id=lookup-foreign-key)|
|foreign-key |String | '' |手动指定使用的关联关系,HBuilderX 3.1.10+ [详情](https://doc.dcloud.net.cn/uniCloud/clientdb?id=lookup-foreign-key)|
`uniCloud.mixinDatacom` 的data
......
......@@ -129,7 +129,7 @@ iOS App打包需要向Apple申请证书。
**注意**
- `history` 模式发行需要后台配置支持,详见:[history 模式的后端配置](https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90)
- 打包后,推荐使用[前端网页托管服务](/uniCloud/hosting),一键上传,自带CDN加速,无需购买虚拟机,无需安装nginx等;
- 打包后,推荐使用[前端网页托管服务](https://doc.dcloud.net.cn/uniCloud/hosting),一键上传,自带CDN加速,无需购买虚拟机,无需安装nginx等;
- 若使用传统服务器部署,建议在服务器端开启 `gzip` 压缩。参考网上的分享:https://juejin.im/post/5af003286fb9a07aac24611b
### 发布为小程序
......
......@@ -26,7 +26,7 @@
* [vue2 升 3 指南](/tutorial/migration-to-vue3.md)
* [ts/typescript 专题](/tutorial/typescript-subject.md)
* [jsx/tsx 语法](/tutorial/syntax-jsx.md)
* [uts语法](/uni-app-x/uts/)
* [uts语法](https://doc.dcloud.net.cn/uni-app-x/uts/)
* 编译器(条件编译)
* [什么是编译器](/tutorial/compiler.md)
* [条件编译处理多端差异](/tutorial/platform.md)
......@@ -36,7 +36,7 @@
* [跨域](/tutorial/CORS.md)
* [宽屏适配](/tutorial/adapt.md)
* [SSR 服务端渲染](/tutorial/ssr.md)
* [前端网页托管](/uniCloud/hosting.md)
* [前端网页托管](https://doc.dcloud.net.cn/uniCloud/hosting.html)
* App 专题
* [nvue 原生渲染](/tutorial/nvue-outline.md)
* [综述](/tutorial/nvue-outline.md)
......@@ -110,7 +110,7 @@
* [未同意隐私政策模式运行](/tutorial/app-disagreemode.md)
* [Google Play上架](/tutorial/android-gp.md)
* [App Store上架](/tutorial/ios-app-store.md)
* [App升级](/uniCloud/upgrade-center.md)
* [App升级](https://doc.dcloud.net.cn/uniCloud/upgrade-center.html)
* 小程序专题
* [组件与WXS](/tutorial/miniprogram-subject.md)
* [使用小程序插件](/tutorial/mp-weixin-plugin.md)
......@@ -141,14 +141,14 @@
* [app 加固](/tutorial/app-security.md)
* [app 隐私合规检测](/tutorial/app-privacy-detect.md)
* 网络安全
* [云端一体安全网络](/uniCloud/secure-network.md)
* [传统服务器与uniCloud安全通信](/uniCloud/uni-cloud-s2s.md)
* [云端一体安全网络](https://doc.dcloud.net.cn/uniCloud/secure-network.html)
* [传统服务器与uniCloud安全通信](https://doc.dcloud.net.cn/uniCloud/uni-cloud-s2s.html)
* 身份安全
* [app一键登录](/univerify.html)
* [app实人认证](/uniCloud/frv/intro.html)
* [图形验证码](/uniCloud/uni-captcha.html)
* [app实人认证](https://doc.dcloud.net.cn/uniCloud/frv/intro.html)
* [图形验证码](https://doc.dcloud.net.cn/uniCloud/uni-captcha.html)
* 服务器安全
* [uniCloud ip防刷](/uniCloud/ip-filter.html)
* [uniCloud ip防刷](https://doc.dcloud.net.cn/uniCloud/ip-filter.html)
* [内容安全审查](https://ext.dcloud.net.cn/plugin?id=5460)
* [国际化专题](/tutorial/i18n.md)
* [国际化开发指南](/tutorial/i18n.md)
......
......@@ -3,7 +3,7 @@
uni-app和5+App提供了一批API,获取客户端一些与安全有关的信息。
::: warning
更推荐使用[uni云端一体安全网络](/uniCloud/secure-network.md),使用安全网络后将无需在使用本章节提供的API。
更推荐使用[uni云端一体安全网络](https://doc.dcloud.net.cn/uniCloud/secure-network.html),使用安全网络后将无需在使用本章节提供的API。
:::
### getSignature
......
......@@ -61,13 +61,13 @@ uni安全网络需要开发者在uniCloud上开通,但并不收费。
如此高安全的保障,在商业项目中都需要花掉不少银子来采购。但DCloud**免费**给uniCloud开发者提供。
uni云端一体安全网络文档:[详见](/uniCloud/secure-network.md)
uni云端一体安全网络文档:[详见](https://doc.dcloud.net.cn/uniCloud/secure-network.html)
## 人机验证
还有一类攻击,攻击者没有破解掉客户端和网络协议,但是用一排排手机墙。
这时,您就需要uni的[一键登录](/univerify.md)[实人认证](/uniCloud/frv/intro.md)
这时,您就需要uni的[一键登录](/univerify.md)[实人认证](https://doc.dcloud.net.cn/uniCloud/frv/intro.html)
`一键登录`是运营商提供的安全方案,它要求手机中必须插sim卡,并且从sim中精准读取手机号,防止手机短信验证码被打码池伪造返回。
......@@ -87,13 +87,13 @@ uni的`一键登录`和`实人认证`不但和uni产品完美结合、快捷开
- 一键登录仅需0.02元/次,比发短信验证码都便宜。
- 实人认证是阶梯价格,[详见](/uniCloud/frv/price.md)
- 实人认证是阶梯价格,[详见](https://doc.dcloud.net.cn/uniCloud/frv/price.html)
这些价格都极具优势。如果您有非常大的量,还可以再联系bd@dcloud.io沟通。
不管是一键登录还是实人认证,在[uni-id](/uniCloud/uni-id/summary.md)里都已经内置集成好。
不管是一键登录还是实人认证,在[uni-id](https://doc.dcloud.net.cn/uniCloud/uni-id/summary.html)里都已经内置集成好。
无需自己写代码。账户的注册、实人认证,这些代码都已经写好并开源在[uni-id-pages](/uniCloud/uni-id-pages.md)项目中。
无需自己写代码。账户的注册、实人认证,这些代码都已经写好并开源在[uni-id-pages](https://doc.dcloud.net.cn/uniCloud/uni-id-pages.html)项目中。
但是注意
::: warning
......@@ -101,7 +101,7 @@ uni的`一键登录`和`实人认证`不但和uni产品完美结合、快捷开
因为这些认证都是收费的,如果没有安全防护,攻击者可以刷你的服务器接口,盗用你的余额来给他提供认证服务,或者干脆就是刷的让你破财。
:::
在人机验证领域,uni还提供了免费的[图形验证码](/uniCloud/uni-captcha.md)
在人机验证领域,uni还提供了免费的[图形验证码](https://doc.dcloud.net.cn/uniCloud/uni-captcha.html)
## 服务器安全
......@@ -111,7 +111,7 @@ uni的`一键登录`和`实人认证`不但和uni产品完美结合、快捷开
如果让攻击者攻击整个阿里云或腾讯云的serverless资源池,那这个池子太大了,那些攻击者根本无法打垮uniCloud服务。
uniCloud还提供了[ip防刷](/uniCloud/ip-filter.md)功能,可以在uniCloud web控制台设置,拉黑某些ip,或者自动屏蔽指定时间内访问次数过高的ip。
uniCloud还提供了[ip防刷](https://doc.dcloud.net.cn/uniCloud/ip-filter.html)功能,可以在uniCloud web控制台设置,拉黑某些ip,或者自动屏蔽指定时间内访问次数过高的ip。
如果您的应用涉及用户提交内容,那么有一个很大的风险就是用户提交非法内容,导致您的应用被公安或运营商禁封。
......
......@@ -619,14 +619,14 @@ sign = sha256(secret:transid)
### 微信小程序说明@callbackweixin
3.6.8+ 支持微信小程序服务器回调,目前仅支持使用 [uni-id](/uniCloud/uni-id/summary.html) 用户体系的小程序,后续支持非 uni-id 用户系统
3.6.8+ 支持微信小程序服务器回调,目前仅支持使用 [uni-id](https://doc.dcloud.net.cn/uniCloud/uni-id/summary.html) 用户体系的小程序,后续支持非 uni-id 用户系统
#### 接入流程
1. 项目使用了 [uni-id-co](/uniCloud/uni-id/summary.md#save-user-token) 并更新到 1.0.8+
2. 使用 [uni-open-bridge](/uniCloud/uni-open-bridge.html) 托管三方开放平台数据
3. 配置 [安全网络](/uniCloud/secure-network.html)
1. 项目使用了 [uni-id-co](https://doc.dcloud.net.cn/uniCloud/uni-id/summary.html#save-user-token) 并更新到 1.0.8+
2. 使用 [uni-open-bridge](https://doc.dcloud.net.cn/uniCloud/uni-open-bridge.html) 托管三方开放平台数据
3. 配置 [安全网络](https://doc.dcloud.net.cn/uniCloud/secure-network.html)
#### 安全注意
......@@ -636,7 +636,7 @@ sign = sha256(secret:transid)
为了提升安全性,建议所有使用激励视频的开发者都要做如下工作来加强保护:
1. 前端代码加密。涉及激励相关的,在manifest中配置好要加密的代码文件,打包后会自动加密相应文件。[详见](https://ask.dcloud.net.cn/article/36437)
2. apk加固。即便前端代码加密,原生层引擎的java代码仍然可能被反编译,需要对apk加固。市面上很多加固服务,比如360加固、爱加密加固均可以自行选择。
3. 使用uni云端一体安全网络,防止伪造客户端攻击。[详见](/uniCloud/secure-network.md)
3. 使用uni云端一体安全网络,防止伪造客户端攻击。[详见](https://doc.dcloud.net.cn/uniCloud/secure-network.html)
3. 使用如下安全类API,防止客户端被篡改
- plus.navigator.getSignature 获取应用签名标识。结合在服务器端存放证书信息,可比对判断App的证书是否被重签 [规范](https://www.html5plus.org/doc/zh_cn/navigator.html#plus.navigator.getSignature)
- plus.navigator.isSimulator 判断App是否运行在模拟器环境 [规范](https://www.html5plus.org/doc/zh_cn/navigator.html#plus.navigator.isSimulator)
......
* [概述](README.md)
* [项目](project.md)
* [页面](page.md)
* 教程
* [与js开发的差别](tutorial/codegap.md)
* [request联网教程](tutorial/request.md)
* [复杂列表开发指南](tutorial/stickynestlist.md)
* [全局变量与状态管理](tutorial/store.md)
* [几种组件标记的概念澄清](tutorial/idref.md)
* vue 框架
* [概述](vue/README.md)
* 运行和调试
* [真机运行](https://uniapp.dcloud.net.cn/tutorial/run/run-app.html)
* [Android审查元素](debug/android-inspector.md)
* [性能优化](performance.md)
* [uni错误规范](https://uniapp.dcloud.net.cn/tutorial/err-spec.html)
# API概述
uni-app x项目的uts代码中可以使用很多API。包括:
- uts的api [详见](../../uts/buildin-object-api/global.md)
- 全局api,前面不需要加`uni.`。如`getApp`
- uni.xxx的内置api。见左侧
- uniCloud.xxx的内置api。见左侧
- dom的api [详见](dom/README.md)
- vue的api [详见](../../tutorial/vue3-api.md)
- 原生api
由于uts可以直接调用Android和iOS的api,所以os和三方sdk的能力都可以在uts中调用。如下:
```vue
<script>
import Build from 'android.os.Build';
export default {
onLoad() {
console.log(Build.MODEL); //调用原生对象,返回手机型号
console.log(uni.getSystemInfoSync().deviceModel); //调用uni API,返回手机型号。与上一行返回值相同
}
}
</script>
```
上面的示例,在页面启动时打印了2行日志,显示手机型号。
- uni.getSystemInfoSync,是uni的api
- import的Build,是Android os的api
可以看出,在uni-app x里,可以直接调用os的能力,不受限制,语法是uts的语法,但需要了解什么功能在原生里是哪个api。
使用`uni.getSystemInfoSync`则比较简单,看uni的文档即可,且可跨平台。
其实,[uni.getSystemInfoSync](https://gitcode.net/dcloud/uni-api/-/blob/master/uni_modules/uni-getSystemInfo/utssdk/app-android/index.uts) 的内部实现就是一个uts模块,底层使用了一样的代码,也是import了android.os.Build。
大多数uni.的api,都是uts开发的,它们会陆续开源在[uni-api](https://gitcode.net/dcloud/uni-api)
插件市场也有很多做好的uts插件,方便开发者拿来即用。[uts插件](https://ext.dcloud.net.cn/?cat1=8&type=UpdatedDate)
虽然上述页面可以直接调用原生能力,但一般原生能力建议封装为[uni_modules](../../plugin/uni_modules.md)形式的[uts插件](../../plugin/uts-plugin.md)。这样方便共享、方便跨平台。
uni-app x 中不再支持plus和weex的API。过于plus api中一些常用的api,在uni-app x中进行了替换增补。
- plus.runtime.quit => [uni.exit](./exit.md)
- plus.runtime.install => [uni.installApk](./install-apk.md)
- plus.runtime.openURL
暂未封装API,但可以直接使用如下代码调用。
```vue
<template>
<view>
<button @click="openSchema('https://uniapp.dcloud.io/uni-app-x')">使用浏览器打开指定URL</button>
<button @click="openSchema('market://details?id=com.tencent.mm')">使用应用商店打开指定App</button>
</view>
</template>
<script>
import Intent from 'android.content.Intent';
import Uri from 'android.net.Uri';
export default {
data() {
return {}
},
methods: {
openSchema(url : string) {
const context = UTSAndroid.getUniActivity()!;
const uri = Uri.parse(url)
const intent = new Intent(Intent.ACTION_VIEW, uri)
intent.setData(uri);
context.startActivity(intent);
}
}
}
</script>
```
\ No newline at end of file
* [概述](README.md)
* 全局
* [getApp](get-app.md)
* [getCurrentPages](get-current-pages.md)
* 基础
* [事件总线event-bus](event-bus.md)
* [拦截器](interceptor.md)
* [获取启动参数](get-launch-options-sync.md)
* [退出应用](exit.md)
* 页面
* [页面跳转](navigator.md)
* [设置导航条颜色](set-navigation-bar-color.md)
* [设置导航条标题](set-navigation-bar-title.md)
* [设置tabbar](set-tabbar.md)
* [页面下拉刷新](pull-down-refresh.md)
* [将页面滚动到指定位置](page-scroll-to.md)
* 元素节点
* [获取element](get-element.md)
* [获取node](nodes-info.md)
* 界面
* [交互反馈](prompt.md)
* [动态加载字体](load-font-face.md)
* [截屏事件](capturescreen.md)
* 网络
* [发起请求request](request.md)
* [上传文件](upload-file.md)
* [下载文件](download-file.md)
* [获取设备网络状态](get-network-type.md)
* [websocket](websocket-global.md)
* 设备
* [获取系统信息](get-system-info.md)
* [获取设备信息](get-device-info.md)
* [获取窗口信息](get-window-info.md)
* [获取app基础信息](get-app-base-info.md)
* [获取app授权设置](get-app-authorize-setting.md)
* [获取系统设置](get-system-setting.md)
* [获取电量信息](get-battery-info.md)
* [安装 APK](install-apk.md)
* [wifi](wifi.md)
* [内存](memory.md)
* [截屏事件](capturescreen.md)
* 媒体
* [拍照和相册选择](choose-image.md)
* [图片预览](preview-image.md)
* [保存图片到相册](save-image-to-photos-album.md)
* 位置
* [获取当前位置](get-location.md)
* 推送
* [推送](push.md)
* 数据存储
* [storage(key-value存储)](storage.md)
<!-- * 文件
* [FileManager](get-file-system-manager) -->
* 登录和验证
<!-- * [一键登录](get-univerify-manager.md) -->
* [实人认证](facial-recognition-verify.md)
* 组件上下文对象
* [web-view组件上下文对象](create-webview-context.md)
* [video组件上下文对象](create-video-context.md)
* uniCloud客户端API
* [概述](unicloud/README.md)
* [云函数](unicloud/function.md)
* [云对象](unicloud/object.md)
* [数据库](unicloud/database.md)
* [云存储](unicloud/storage.md)
* [其他API](unicloud/utils.md)
* [未支持的API及替代方案](ext.md)
\ No newline at end of file
## uni.onUserCaptureScreen(callback?) @onusercapturescreen
<!-- UTSAPIJSON.onUserCaptureScreen.description -->
<!-- UTSAPIJSON.onUserCaptureScreen.param -->
<!-- UTSAPIJSON.onUserCaptureScreen.returnValue -->
<!-- UTSAPIJSON.onUserCaptureScreen.compatibility -->
<!-- UTSAPIJSON.onUserCaptureScreen.tutorial -->
## uni.offUserCaptureScreen(callback?) @offusercapturescreen
<!-- UTSAPIJSON.offUserCaptureScreen.description -->
<!-- UTSAPIJSON.offUserCaptureScreen.param -->
<!-- UTSAPIJSON.offUserCaptureScreen.returnValue -->
<!-- UTSAPIJSON.offUserCaptureScreen.compatibility -->
<!-- UTSAPIJSON.offUserCaptureScreen.tutorial -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## tips
- 本文的截屏指手机自带的截屏事件的监听和取消监听,由用户操作手机按键触发。如需通过代码对view截屏,另见API [takeSnapshot](../dom/element.md#takesnapshot)
\ No newline at end of file
## uni.chooseImage(options) @chooseimage
<!-- UTSAPIJSON.chooseImage.description -->
<!-- UTSAPIJSON.chooseImage.param -->
<!-- UTSAPIJSON.chooseImage.returnValue -->
<!-- UTSAPIJSON.chooseImage.compatibility -->
<!-- UTSAPIJSON.chooseImage.tutorial -->
<!-- UTSAPIJSON.choose-image.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## Tips
* 获取手机端app是否拥有摄像头权限,请使用API [uni.getAppAuthorizeSetting](get-app-authorize-setting.md)
\ No newline at end of file
## uni.createVideoContext(videoId, component?) @createvideocontext
<!-- UTSAPIJSON.createVideoContext.description -->
<!-- UTSAPIJSON.createVideoContext.param -->
<!-- UTSAPIJSON.createVideoContext.returnValue -->
<!-- UTSAPIJSON.createVideoContext.example -->
<!-- UTSAPIJSON.createVideoContext.compatibility -->
<!-- UTSAPIJSON.createVideoContext.tutorial -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.createWebviewContext(webviewId, component?) @createwebviewcontext
<!-- UTSAPIJSON.createWebviewContext.description -->
<!-- UTSAPIJSON.createWebviewContext.param -->
<!-- UTSAPIJSON.createWebviewContext.returnValue -->
<!-- UTSAPIJSON.createWebviewContext.example -->
<!-- UTSAPIJSON.createWebviewContext.compatibility -->
<!-- UTSAPIJSON.createWebviewContext.tutorial -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.downloadFile(options) @downloadfile
<!-- UTSAPIJSON.downloadFile.description -->
<!-- UTSAPIJSON.downloadFile.param -->
<!-- UTSAPIJSON.downloadFile.returnValue -->
<!-- UTSAPIJSON.downloadFile.example -->
<!-- UTSAPIJSON.downloadFile.compatibility -->
<!-- UTSAPIJSON.downloadFile.tutorial -->
<!-- UTSAPIJSON.download-file.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## Tips
- 3.98以下版本,下载的文件存放在应用沙盒非cache目录,不会自动删除。3.98及以上版本迁移到应用临时目录(Android原生应用沙盒目录下的cache目录),由系统清理管理。
\ No newline at end of file
## uni.$on(eventName, callback) @$on
<!-- UTSAPIJSON.$on.description -->
<!-- UTSAPIJSON.$on.param -->
<!-- UTSAPIJSON.$on.returnValue -->
<!-- UTSAPIJSON.$on.example -->
<!-- UTSAPIJSON.$on.compatibility -->
<!-- UTSAPIJSON.$on.tutorial -->
## uni.$off(eventName, callback) @$off
<!-- UTSAPIJSON.$off.description -->
<!-- UTSAPIJSON.$off.param -->
<!-- UTSAPIJSON.$off.returnValue -->
<!-- UTSAPIJSON.$off.example -->
<!-- UTSAPIJSON.$off.compatibility -->
<!-- UTSAPIJSON.$off.tutorial -->
## uni.$once(eventName, callback) @$once
<!-- UTSAPIJSON.$once.description -->
<!-- UTSAPIJSON.$once.param -->
<!-- UTSAPIJSON.$once.returnValue -->
<!-- UTSAPIJSON.$once.example -->
<!-- UTSAPIJSON.$once.compatibility -->
<!-- UTSAPIJSON.$once.tutorial -->
## uni.$emit(eventName, args?) @$emit
<!-- UTSAPIJSON.$emit.description -->
<!-- UTSAPIJSON.$emit.param -->
<!-- UTSAPIJSON.$emit.returnValue -->
<!-- UTSAPIJSON.$emit.example -->
<!-- UTSAPIJSON.$emit.compatibility -->
<!-- UTSAPIJSON.$emit.tutorial -->
<!-- UTSAPIJSON.event-bus.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.exit(options?) @exit
<!-- UTSAPIJSON.exit.description -->
<!-- UTSAPIJSON.exit.param -->
<!-- UTSAPIJSON.exit.returnValue -->
<!-- UTSAPIJSON.exit.compatibility -->
本API仅Android App生效。
Android平台的应用退出分热退出和冷退出。
- 冷退出是彻底杀掉
- 热退出是关闭可见的activity,后台进程不退出(比如push)
基本上主流Android App都是热退出。本API也是热退出。
热退出,即通知了os:这个app用户不用了,在os需要时可以回收。如果在os回收之前,用户又启动这个app,会感觉启动速度更快一些。
<!-- UTSAPIJSON.exit.tutorial -->
<!-- UTSAPIJSON.exit.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
# 其它api
插件市场和hello示例中还有一批可替代uni内置api的插件或示例代码,比如:
- [剪切板](https://ext.dcloud.net.cn/search?q=%E5%89%AA%E5%88%87%E6%9D%BF&orderBy=Relevance&cat1=8&cat2=81)`uni.setClipboardData``uni.getClipboardData`
- [拨打电话](https://ext.dcloud.net.cn/plugin?id=15235)`uni.makePhoneCall`
- [打开三方应用](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/dev/pages/template/schema/schema.uvue):打开浏览器、应用商店、地图并传参。`plus.openUrl`
- [分享](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/dev/pages/template/share/share.uvue)`uni.shareWithSystem`
- 打开文件:`uni.openDocument`[hello uts示例](](https://gitcode.net/dcloud/hello-uts/-/blob/dev/uni_modules/uts-nativepage/utssdk/app-android/index.uts))、[插件市场](https://ext.dcloud.net.cn/plugin?id=12731)
- [扫码](https://ext.dcloud.net.cn/search?q=%E6%89%AB%E7%A0%81&cat1=8&type=UpdatedDate)`uni.scanCode`
- [文件选择](https://ext.dcloud.net.cn/search?q=%E6%96%87%E4%BB%B6%E9%80%89%E6%8B%A9&cat1=8&cat2=81)`uni.chooseFile`
- [蓝牙](https://ext.dcloud.net.cn/search?q=%E8%93%9D%E7%89%99&orderBy=Relevance&cat1=8&cat2=81)
- [nfc](https://ext.dcloud.net.cn/search?q=nfc&orderBy=Relevance&cat1=8&cat2=81)
# uni实人认证
uni实人认证是DCloud与合作伙伴共同推出的金融级实人认证服务,通过对比人脸、活体检测、姓名和身份证号码,来确认用户身份的有效性。
该业务的完整业务介绍另见:[实人认证](https://uniapp.dcloud.net.cn/uniCloud/frv/intro.html)
本文是 uni-app x 中涉及该业务的API的介绍。
## uni.getFacialRecognitionMetaInfo() @getfacialrecognitionmetainfo
<!-- UTSAPIJSON.getFacialRecognitionMetaInfo.description -->
<!-- UTSAPIJSON.getFacialRecognitionMetaInfo.param -->
<!-- UTSAPIJSON.getFacialRecognitionMetaInfo.returnValue -->
<!-- UTSAPIJSON.getFacialRecognitionMetaInfo.compatibility -->
<!-- UTSAPIJSON.getFacialRecognitionMetaInfo.tutorial -->
## uni.startFacialRecognitionVerify(faceStyle) @startfacialrecognitionverify
<!-- UTSAPIJSON.startFacialRecognitionVerify.description -->
<!-- UTSAPIJSON.startFacialRecognitionVerify.param -->
<!-- UTSAPIJSON.startFacialRecognitionVerify.returnValue -->
<!-- UTSAPIJSON.startFacialRecognitionVerify.compatibility -->
<!-- UTSAPIJSON.startFacialRecognitionVerify.tutorial -->
<!-- UTSAPIJSON.facial-recognition-verify.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## Tips
* 获取手机端app是否拥有摄像头权限,请使用API [uni.getAppAuthorizeSetting](get-app-authorize-setting.md)
\ No newline at end of file
# 文件系统
文件系统提供一套跨平台操作文件的管理接口,包括文件和目录的增删改名、获取信息、读写文件等常用功能。
通过[uni.getFileSystemManager](filemanager.md)可以获取到文件系统管理器,所有文件系统的管理操作通过 [FileSystemManager](filemanager.md#FileSystemManager) 来调用。
```uts
const fs = uni.getFileSystemManager()
```
文件主要分两大类:
- 项目包文件:指 uni-app x 项目目录中添加的文件,比如static目录下的文件。Android发行后存放在assets目录下。
- 本地文件:指 uni-app x 应用在手机端运行时可访问的磁盘文件。又分以下目录:
+ 应用沙盒目录:App平台原生应用的沙盒目录,其中包括缓存文件目录和用户文件目录
* 缓存文件目录:App平台运行过程中框架保存缓存文件的目录
* 用户文件目录:App平台提供给开发者操作的本地文件目录
## 项目包文件
项目包文件放置应用首次加载时需要的文件,对于内容较大或需要动态更新的文件,不推荐添加到项目包文件中,可以在应用启动后联网将文件下载到本地。
推荐将文件放到static目录(uni_modules下也有static目录),详情参考[工程目录结构](https://uniapp.dcloud.net.cn/tutorial/project.html#static)
没有在static目录的静态文件(比如image src指定静态路径或import),发行后会变编译到与static同级的assets目录,其中的文件名会加入随机数以避免重名。
因为随机数的存在,导致很难使用FileSystemManager访问。所以还是推荐使用static目录。
**通过FileSystemManager访问项目包文件**
通过路径访问项目包文件需从项目根目录开始写文件路径,如:/static/uni.png、/uni_modules/xxx/static/clear.png。
>注意:项目包文件仅可读取和复制,无法动态修改或删除。修改项目包文件需要重新发布新版本。
**真机运行注意**
App端真机运行期间会做特殊处理,将项目包文件同步到`应用沙盒目录`下的特定目录:
- Android平台
保存在应用专属存储空间的外置存储空间根目录下的apps目录,通常为“/sdcard/Android/data/%应用包名%/apps/%应用AppID%/www/”
- iOS平台
保存在应用沙盒目录下的Documents/uni-app-x目录,通常为“/%应用沙盒目录%/Documents/uni-app-x/apps/%应用AppID%/www/”
## 本地文件
本地文件是指应用安装到设备(通常指手机)后,系统会提供一块独立的文件存储区域。在App端将会以应用维度隔离,即在同一台设备,不同应用间的本地文件不能直接相互访问。
本地文件路径格式为:
```
{{协议名}}://文件路径
```
> App端,协议名为"unifile",不应该直接拼写协议名路径访问本地文件,推荐使用uni.env中的目录常量获取本地文件目录的路径。
本地文件沙盒目录,分内置和外置。外置可以在Android手机自带的系统文件管理器里看到,并且用户可以改动。内置的保护级别更高,无法在系统文件管理器中看到。
**通过uni.env的目录常量访问本地文件**
以下示例为在`用户文件目录`下写入hello.txt文件:
```ts
const fs = uni.getFileSystemManager();
fs.writeFile({
filePath: `${uni.env.USER_DATA_PATH}/hello.txt`,
data: 'hello uni-app x!',
encoding: 'utf-8'
} as WriteFileOptions);
```
### 外置应用沙盒目录
目录常量名称:`uni.env.SANDBOX_PATH`
App端专有目录,为应用沙盒根目录,其下包含了`缓存文件目录``用户文件目录`。此目录在不同平台差异较大,不建议直接使用此目录,需开发者根据平台特性谨慎操作。
实际保存的目录在不同平台存在差异:
- Android平台
应用专属存储空间的外置存储空间根目录,通常为“/sdcard/Android/data/%应用包名%/”,其下的cache目录为`缓存文件目录`,其下的files目录为`用户文件目录`
- iOS平台
应用沙盒虚拟目录,其下包括Document、Library、tmp目录,此目录只可读,不可创建其它目录
本目录可以在Android系统的文件管理器中看到。用户在文件管理器中可以查阅删改。手机被root后的沙盒机制也会失效,可以被其他app操作。
#### 缓存文件目录
目录常量名称:`uni.env.CACHE_PATH`
App端本地缓存文件目录保存应用运行过程中产生的缓存文件,操作系统会在存储空间不足时清除缓存文件,因此不要在此目录中保存应用的关键业务数据文件。
实际保存的目录在不同平台存在差异:
- Android平台
应用专属存储空间的外置存储空间根目录下的cache目录,通常为“/sdcard/Android/data/%应用包名%/cache/”
- iOS平台
应用沙盒目录下的Library/Caches目录
uni-app x的部分内置API会产生临时文件会放置在本cache目录,如:
- uni.downloadFile下载的文件
- uni.uploadFile上传的文件
- uni.chooseImage的拍照或选择的相册文件
<!-- - 录音的文件 -->
- dom element的截图API
#### 用户文件目录
目录常量名称:`uni.env.USER_DATA_PATH `
App端用户文件目录提供给开发者在应用运行期保存业务逻辑文件,此目录不会被操作系统自动清除,由开发者完全自由管理。
实际保存的目录在不同平台存在差异:
- Android平台
应用专属存储空间的外置存储空间根目录下的files目录,通常为“/sdcard/Android/data/%应用包名%/files/”
- iOS平台
应用沙盒目录下的Document目录
### 内置应用沙盒目录
目录常量名称:`uni.env.ANDROID_INTERNAL_SANDBOX_PATH`
uni-app x框架的一些内置组件和API会涉及缓存文件,存放到本目录,如:
- image/video组件的网络图片缓存
<!-- - 网络字体缓存? -->
\ No newline at end of file
## uni.getAppAuthorizeSetting() @getappauthorizesetting
<!-- UTSAPIJSON.getAppAuthorizeSetting.description -->
<!-- UTSAPIJSON.getAppAuthorizeSetting.param -->
<!-- UTSAPIJSON.getAppAuthorizeSetting.returnValue -->
<!-- UTSAPIJSON.getAppAuthorizeSetting.example -->
<!-- UTSAPIJSON.getAppAuthorizeSetting.compatibility -->
<!-- UTSAPIJSON.getAppAuthorizeSetting.tutorial -->
<!-- UTSAPIJSON.get-app-authorize-setting.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.getAppBaseInfo(options?) @getappbaseinfo
<!-- UTSAPIJSON.getAppBaseInfo.description -->
<!-- UTSAPIJSON.getAppBaseInfo.param -->
<!-- UTSAPIJSON.getAppBaseInfo.returnValue -->
<!-- UTSAPIJSON.getAppBaseInfo.example -->
<!-- UTSAPIJSON.getAppBaseInfo.compatibility -->
<!-- UTSAPIJSON.getAppBaseInfo.tutorial -->
<!-- UTSAPIJSON.get-app-base-info.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## getApp() @getapp
<!-- UTSAPIJSON.getApp.description -->
<!-- UTSAPIJSON.getApp.param -->
<!-- UTSAPIJSON.getApp.returnValue -->
<!-- UTSAPIJSON.getApp.example -->
<!-- UTSAPIJSON.getApp.compatibility -->
<!-- UTSAPIJSON.getApp.tutorial -->
<!-- UTSAPIJSON.get-app.example -->
以上示例,getApp()后调用了app.uvue里定义的increasetLifeCycleNum方法。app.uvue的源码[另见](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/alpha/App.uvue)
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.getBatteryInfo(options) @getbatteryinfo
<!-- UTSAPIJSON.getBatteryInfo.description -->
<!-- UTSAPIJSON.getBatteryInfo.param -->
<!-- UTSAPIJSON.getBatteryInfo.returnValue -->
<!-- UTSAPIJSON.getBatteryInfo.example -->
<!-- UTSAPIJSON.getBatteryInfo.compatibility -->
<!-- UTSAPIJSON.getBatteryInfo.tutorial -->
## uni.getBatteryInfoSync() @getbatteryinfosync
<!-- UTSAPIJSON.getBatteryInfoSync.description -->
<!-- UTSAPIJSON.getBatteryInfoSync.param -->
<!-- UTSAPIJSON.getBatteryInfoSync.returnValue -->
<!-- UTSAPIJSON.getBatteryInfoSync.example -->
<!-- UTSAPIJSON.getBatteryInfoSync.compatibility -->
<!-- UTSAPIJSON.getBatteryInfoSync.tutorial -->
<!-- UTSAPIJSON.get-battery-info.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## getCurrentPages() @getcurrentpages
<!-- UTSAPIJSON.getCurrentPages.description -->
<!-- UTSAPIJSON.getCurrentPages.param -->
<!-- UTSAPIJSON.getCurrentPages.returnValue -->
<!-- UTSAPIJSON.getCurrentPages.example -->
<!-- UTSAPIJSON.getCurrentPages.compatibility -->
<!-- UTSAPIJSON.getCurrentPages.tutorial -->
<!-- UTSAPIJSON.get-current-pages.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.getDeviceInfo(options?) @getdeviceinfo
<!-- UTSAPIJSON.getDeviceInfo.description -->
<!-- UTSAPIJSON.getDeviceInfo.param -->
<!-- UTSAPIJSON.getDeviceInfo.returnValue -->
<!-- UTSAPIJSON.getDeviceInfo.example -->
<!-- UTSAPIJSON.getDeviceInfo.compatibility -->
<!-- UTSAPIJSON.getDeviceInfo.tutorial -->
<!-- UTSAPIJSON.get-device-info.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.getElementById(id) @getelementbyid
<!-- UTSAPIJSON.getElementById.description -->
<!-- UTSAPIJSON.getElementById.param -->
`3.93+` 支持泛型,可通过 `uni.getElementById<ElementType>(id)` 获取指定类型的元素。对于组件有自带方法的情况,通过泛型指定具体的元素类型,就可以调用该类型组件的专用方法,比如unicloud-db组件。\
具体的组件元素类型,可查阅`组件文档/组件类型`获取。
<!-- UTSAPIJSON.getElementById.returnValue -->
<!-- UTSAPIJSON.getElementById.example -->
<!-- UTSAPIJSON.getElementById.compatibility -->
<!-- UTSAPIJSON.getElementById.tutorial -->
<!-- UTSAPIJSON.get-element.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## uni.getFileSystemManager() @getfilesystemmanager
<!-- UTSAPIJSON.getFileSystemManager.description -->
文件管理器对象,用于操作应用可访问的本地文件空间,在app-Android上是沙盒目录。
可实现目录和文件的创建、删除、改名或改路径、遍历目录、获取文件信息、读写文件。
<!-- UTSAPIJSON.getFileSystemManager.param -->
<!-- UTSAPIJSON.getFileSystemManager.returnValue -->
<!-- UTSAPIJSON.getFileSystemManager.compatibility -->
<!-- UTSAPIJSON.getFileSystemManager.tutorial -->
<!-- UTSAPIJSON.getFileSystemManager.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.getLaunchOptionsSync() @getlaunchoptionssync
<!-- UTSAPIJSON.getLaunchOptionsSync.description -->
<!-- UTSAPIJSON.getLaunchOptionsSync.param -->
<!-- UTSAPIJSON.getLaunchOptionsSync.returnValue -->
<!-- UTSAPIJSON.getLaunchOptionsSync.example -->
<!-- UTSAPIJSON.getLaunchOptionsSync.compatibility -->
<!-- UTSAPIJSON.getLaunchOptionsSync.tutorial -->
<!-- UTSAPIJSON.get-launch-options-sync.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.getLocation(options) @getlocation
<!-- UTSAPIJSON.getLocation.description -->
<!-- UTSAPIJSON.getLocation.param -->
<!-- UTSAPIJSON.getLocation.returnValue -->
<!-- UTSAPIJSON.getLocation.compatibility -->
### 注意
uni-app x的定位,默认是系统定位,system。
system的定位仅支持wgs84坐标系、不支持逆地址解析、且某些老型号国产Android机因gms问题不支持系统定位、国产Rom可能不支持高度信息。
如需更强的定位能力,需加载专业定位sdk。
真机运行基座不包含三方定位sdk。
三方定位sdk方面,暂不支持高德、百度,但支持腾讯定位。
可下载[腾讯定位插件](https://ext.dcloud.net.cn/plugin?id=14569),在插件中配置key打包后生效。
上述腾讯定位插件属于[ext api插件](../../api/extapi.md),引用到工程后,会覆盖uni.getLocation的实现,替换掉系统定位。
如需其他定位,请在插件市场搜索定位相关的uts插件。
获取手机端app是否拥有定位权限,请使用API [uni.getAppAuthorizeSetting](get-app-authorize-setting.md)
不管系统定位、还是三方sdk定位,都有很多注意事项,包括gms、坐标系、隐私和权限等,请仔细阅读下面的参考链接。
<!-- UTSAPIJSON.getLocation.tutorial -->
<!-- UTSAPIJSON.get-location.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## uni.getNetworkType(options) @getnetworktype
<!-- UTSAPIJSON.getNetworkType.description -->
<!-- UTSAPIJSON.getNetworkType.param -->
<!-- UTSAPIJSON.getNetworkType.returnValue -->
<!-- UTSAPIJSON.getNetworkType.example -->
<!-- UTSAPIJSON.getNetworkType.compatibility -->
<!-- UTSAPIJSON.getNetworkType.tutorial -->
<!-- UTSAPIJSON.get-network-type.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.getSystemInfo(options) @getsysteminfo
<!-- UTSAPIJSON.getSystemInfo.description -->
uni-app 提供了异步(`uni.getSystemInfo`)和同步(`uni.getSystemInfoSync`)的2个API获取系统信息。
按照运行环境层级排序,从底层向上,systemInfo有6个概念:
- `device`:运行应用的设备,如iphone、huawei
- `os`:设备的操作系统,如 ios、andriod、windows、mac、linux
- `rom`:基于操作系统的定制,Android系统特有概念,如miui、鸿蒙
- `host`:运行应用的宿主程序,即OS和应用之间的运行环境,如浏览器、微信等小程序宿主、集成uniMPSDK的App。uni-app直接开发的app没有host概念
- `uni`:uni-app框架相关的信息,如uni-app框架的编译器版本、运行时版本
- `app`:开发者的应用相关的信息,如应用名称、版本
[详见](https://uniapp.dcloud.net.cn/api/system/info.html#getsysteminfo)
<!-- UTSAPIJSON.getSystemInfo.param -->
<!-- UTSAPIJSON.getSystemInfo.returnValue -->
<!-- UTSAPIJSON.getSystemInfo.example -->
<!-- UTSAPIJSON.getSystemInfo.compatibility -->
<!-- UTSAPIJSON.getSystemInfo.tutorial -->
## uni.getSystemInfoSync() @getsysteminfosync
<!-- UTSAPIJSON.getSystemInfoSync.description -->
<!-- UTSAPIJSON.getSystemInfoSync.param -->
<!-- UTSAPIJSON.getSystemInfoSync.returnValue -->
<!-- UTSAPIJSON.getSystemInfoSync.example -->
<!-- UTSAPIJSON.getSystemInfoSync.compatibility -->
<!-- UTSAPIJSON.getSystemInfoSync.tutorial -->
<!-- UTSAPIJSON.get-system-info.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.getSystemSetting() @getsystemsetting
<!-- UTSAPIJSON.getSystemSetting.description -->
<!-- UTSAPIJSON.getSystemSetting.param -->
<!-- UTSAPIJSON.getSystemSetting.returnValue -->
<!-- UTSAPIJSON.getSystemSetting.example -->
<!-- UTSAPIJSON.getSystemSetting.compatibility -->
<!-- UTSAPIJSON.getSystemSetting.tutorial -->
<!-- UTSAPIJSON.get-system-setting.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.getUniverifyManager() @getuniverifymanager
<!-- UTSAPIJSON.getUniverifyManager.description -->
App一键登陆,封装了个推的一键登陆sdk,其内部再次封装了中国三大电信运营商提供的sdk。通过运营商提供的服务,可以在手机sim卡信号正常的情况下,通过云端接口获取到当前用户的手机号。
App一键登陆是替代短信验证码登录的更优选择:对开发者而言更便宜、对用户而言体验更好。
一键登陆涉及业务开通和付费,涉及客户端和服务器交互,有较多文档:
1. 业务介绍:介绍业务流程、开通和付费。[详见](https://uniapp.dcloud.net.cn/univerify.html)
2. 客户端API,即本文
3. 服务器API,[详见](https://uniapp.dcloud.net.cn/uniCloud/uni-login/dev.html)
<!-- UTSAPIJSON.getUniverifyManager.param -->
<!-- UTSAPIJSON.getUniverifyManager.returnValue -->
<!-- UTSAPIJSON.getUniverifyManager.compatibility -->
<!-- UTSAPIJSON.getUniverifyManager.tutorial -->
<!-- UTSAPIJSON.getUniverifyManager.example -->
## Tips
- 运营商对一键登陆给用户呈现的ui有强制要求。(需补充细节)
- 目前一键登陆的UI可自定义性有限。仅支持配置登录页全屏/半屏、登录页背景色、登录按钮文案以及登录页logo。
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.getWindowInfo() @getwindowinfo
<!-- UTSAPIJSON.getWindowInfo.description -->
<!-- UTSAPIJSON.getWindowInfo.param -->
<!-- UTSAPIJSON.getWindowInfo.returnValue -->
<!-- UTSAPIJSON.getWindowInfo.example -->
<!-- UTSAPIJSON.getWindowInfo.compatibility -->
<!-- UTSAPIJSON.getWindowInfo.tutorial -->
<!-- UTSAPIJSON.get-window-info.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.installApk(options) @installapk
<!-- UTSAPIJSON.installApk.description -->
<!-- UTSAPIJSON.installApk.param -->
<!-- UTSAPIJSON.installApk.returnValue -->
<!-- UTSAPIJSON.installApk.compatibility -->
<!-- UTSAPIJSON.installApk.tutorial -->
<!-- UTSAPIJSON.install-apk.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.addInterceptor(name, interceptor) @addinterceptor
<!-- UTSAPIJSON.addInterceptor.description -->
<!-- UTSAPIJSON.addInterceptor.param -->
<!-- UTSAPIJSON.addInterceptor.returnValue -->
<!-- UTSAPIJSON.addInterceptor.compatibility -->
<!-- UTSAPIJSON.addInterceptor.tutorial -->
## uni.removeInterceptor(name, interceptor?) @removeinterceptor
<!-- UTSAPIJSON.removeInterceptor.description -->
<!-- UTSAPIJSON.removeInterceptor.param -->
<!-- UTSAPIJSON.removeInterceptor.returnValue -->
<!-- UTSAPIJSON.removeInterceptor.compatibility -->
<!-- UTSAPIJSON.removeInterceptor.tutorial -->
<!-- UTSAPIJSON.interceptor.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## Tips@tips
* 目前仅以下接口支持拦截器:navigateTo、redirectTo、reLaunch、switchTab、navigateBack、loadFontFace、pageScrollTo、startPullDownRefresh、setNavigationBarColor、setNavigationBarTitle、setTabBarBadge、removeTabBarBadge、setTabBarItem、setTabBarStyle、hideTabBar、showTabBar、showTabBarRedDot、hideTabBarRedDot
* 如需拦截request,可在插件市场搜索[拦截器插件](https://ext.dcloud.net.cn/search?q=%E6%8B%A6%E6%88%AA%E5%99%A8&uni-appx=1)
\ No newline at end of file
## uni.loadFontFace(options) @loadfontface
<!-- UTSAPIJSON.loadFontFace.description -->
<!-- UTSAPIJSON.loadFontFace.param -->
<!-- UTSAPIJSON.loadFontFace.returnValue -->
<!-- UTSAPIJSON.loadFontFace.example -->
<!-- UTSAPIJSON.loadFontFace.compatibility -->
<!-- UTSAPIJSON.loadFontFace.tutorial -->
<!-- UTSAPIJSON.load-font-face.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.onMemoryWarning(UTSCallback) @onmemorywarning
<!-- UTSAPIJSON.onMemoryWarning.description -->
<!-- UTSAPIJSON.onMemoryWarning.param -->
<!-- UTSAPIJSON.onMemoryWarning.returnValue -->
<!-- UTSAPIJSON.onMemoryWarning.compatibility -->
<!-- UTSAPIJSON.onMemoryWarning.tutorial -->
## uni.offMemoryWarning(callback?) @offmemorywarning
<!-- UTSAPIJSON.offMemoryWarning.description -->
<!-- UTSAPIJSON.offMemoryWarning.param -->
<!-- UTSAPIJSON.offMemoryWarning.returnValue -->
<!-- UTSAPIJSON.offMemoryWarning.compatibility -->
<!-- UTSAPIJSON.offMemoryWarning.tutorial -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.navigateTo(options) @navigateto
<!-- UTSAPIJSON.navigateTo.description -->
<!-- UTSAPIJSON.navigateTo.param -->
<!-- UTSAPIJSON.navigateTo.returnValue -->
<!-- UTSAPIJSON.navigateTo.example -->
<!-- UTSAPIJSON.navigateTo.compatibility -->
<!-- UTSAPIJSON.navigateTo.tutorial -->
## uni.redirectTo(options) @redirectto
<!-- UTSAPIJSON.redirectTo.description -->
<!-- UTSAPIJSON.redirectTo.param -->
<!-- UTSAPIJSON.redirectTo.returnValue -->
<!-- UTSAPIJSON.redirectTo.example -->
<!-- UTSAPIJSON.redirectTo.compatibility -->
<!-- UTSAPIJSON.redirectTo.tutorial -->
## uni.reLaunch(options) @relaunch
<!-- UTSAPIJSON.reLaunch.description -->
<!-- UTSAPIJSON.reLaunch.param -->
<!-- UTSAPIJSON.reLaunch.returnValue -->
<!-- UTSAPIJSON.reLaunch.example -->
<!-- UTSAPIJSON.reLaunch.compatibility -->
<!-- UTSAPIJSON.reLaunch.tutorial -->
## uni.switchTab(options) @switchtab
<!-- UTSAPIJSON.switchTab.description -->
<!-- UTSAPIJSON.switchTab.param -->
<!-- UTSAPIJSON.switchTab.returnValue -->
<!-- UTSAPIJSON.switchTab.example -->
<!-- UTSAPIJSON.switchTab.compatibility -->
<!-- UTSAPIJSON.switchTab.tutorial -->
## uni.navigateBack(options?) @navigateback
<!-- UTSAPIJSON.navigateBack.description -->
<!-- UTSAPIJSON.navigateBack.param -->
<!-- UTSAPIJSON.navigateBack.returnValue -->
<!-- UTSAPIJSON.navigateBack.example -->
<!-- UTSAPIJSON.navigateBack.compatibility -->
<!-- UTSAPIJSON.navigateBack.tutorial -->
<!-- UTSAPIJSON.navigator.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## Bug & Tips@tips
* ``navigateTo``, ``redirectTo`` 只能打开非 tabBar 页面。
* ``switchTab`` 只能打开 ``tabBar`` 页面。
* ``reLaunch`` 可以打开任意页面。
* 页面底部的 ``tabBar`` 由页面决定,即只要是定义为 ``tabBar`` 的页面,底部都有 ``tabBar``
* 不能在首页 ```onReady``` 之前进行页面跳转。
\ No newline at end of file
## uni.createSelectorQuery() @createselectorquery
<!-- UTSAPIJSON.createSelectorQuery.description -->
<!-- UTSAPIJSON.createSelectorQuery.param -->
**selector 说明:**
``selector`` 类似于 CSS 的选择器,但仅支持下列语法。
- ID选择器:``#the-id``
- class选择器:``.a-class``
<!-- UTSAPIJSON.createSelectorQuery.returnValue -->
##### NodeInfo 属性值
|属性 |类型 |说明 |
|--- |--- |--- |
|id |String |节点的 ID |
|dataset|Object |节点的 dataset |
|left |Number |节点的左边界坐标 |
|right |Number |节点的右边界坐标 |
|top |Number |节点的上边界坐标 |
|bottom |Number |节点的下边界坐标 |
|width |Number |节点的宽度 |
|height |Number |节点的高度 |
<!-- UTSAPIJSON.createSelectorQuery.returnValue -->
<!-- UTSAPIJSON.createSelectorQuery.example -->
<!-- UTSAPIJSON.createSelectorQuery.compatibility -->
<!-- UTSAPIJSON.createSelectorQuery.tutorial -->
<!-- UTSAPIJSON.nodes-info.example -->
组件内使用
`this.createSelectorQuery()`, 等效于 `uni.createSelectorQuery().in(this)`
```html
<template>
<view>
<button @click="getNodeInfo">getNodeInfo</button>
<view class="rect-1-2">
<view class="rect rect1"></view>
<view class="rect rect2"></view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
nodeInfoList: [] as NodeInfo[]
}
},
props: {
},
methods: {
getNodeInfo() {
this.createSelectorQuery().select('.rect1').boundingClientRect().exec((ret) => {
this.nodeInfoList.length = 0
this.nodeInfoList.push(ret[0] as NodeInfo)
})
}
}
}
</script>
```
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
**exec 示例说明:**
`exec()` 返回所有动作的集合,每一项的数据类型取决于查询动作,结果排序按照调用动作顺序
示例:
```js
this.createSelectorQuery().select('.rect1').boundingClientRect().exec()
// 共返回 1 条结果,第一项数据类型为 NodeInfo
result = [ {} ]
```
```js
this.createSelectorQuery().selectAll('.rect1').boundingClientRect().exec()
// 共返回 1 条结果,第一项数据类型为 NodeInfo[]
result = [ [{},{}] ]
```
```js
this.createSelectorQuery().select('.rect1').selectAll('.rect2').boundingClientRect().exec()
// 共返回 2 条结果,第一项数据类型为 NodeInfo,第二项数据类型类型为 NodeInfo[]
result = [ {}, [{},{}] ]
```
## uni.pageScrollTo(options) @pagescrollto
<!-- UTSAPIJSON.pageScrollTo.description -->
可以滚动到指定的scrollTop值处,也可以滚动到指定的目标元素处(通过css选择器selector), 仅支持一级 class
app-uvue下,只有页面的根元素为scroll-view时,本API才生效。[详见](../css/readme.md#pagescroll)
<!-- UTSAPIJSON.pageScrollTo.param -->
`scrollTop``selector` 必须指定其中一个属性,否者触发 `fail` 回调
<!-- UTSAPIJSON.pageScrollTo.returnValue -->
<!-- UTSAPIJSON.pageScrollTo.example -->
<!-- UTSAPIJSON.pageScrollTo.compatibility -->
<!-- UTSAPIJSON.pageScrollTo.tutorial -->
**selector 语法**
selector类似于 CSS 的选择器,但仅支持下列语法。
- ID选择器:#the-id
- class选择器(可以连续指定多个):`.a-class.another-class`
- 子元素选择器:`.the-parent > .the-child`
- 后代选择器:`.the-ancestor .the-descendant`
- 跨自定义组件的后代选择器:`.the-ancestor >>> .the-descendant`
- 多选择器的并集:`#a-node, .some-other-nodes`
## uni-app x 注意事项
1. app-uvue支持的选择器较少,不支持ID选择器,[详见](uni-app-x/css/README.md#选择器)
2. app-uvue的页面滚动,是由页面最外层的scroll-view模拟的,如果页面最外层不是scroll-view,无法使用本api。[详见](uni-app-x/css/README.md#pagescroll)
3. app-uvue的scroll-view滚动时,如需动画,则需要在scroll-view的属性中配置 `scroll-with-animation="true"`[详见](component/scroll-view.md)
4. scroll-view的滚动,设置其scrollTop即可。[详见](component/scroll-view.md)
**示例**
```javascript
uni.pageScrollTo({
scrollTop: 0,
duration: 300
});
```
<!-- UTSAPIJSON.page-scroll-to.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.previewImage(options) @previewimage
<!-- UTSAPIJSON.previewImage.description -->
<!-- UTSAPIJSON.previewImage.param -->
<!-- UTSAPIJSON.previewImage.returnValue -->
<!-- UTSAPIJSON.previewImage.example -->
<!-- UTSAPIJSON.previewImage.compatibility -->
<!-- UTSAPIJSON.previewImage.tutorial -->
## uni.closePreviewImage(options) @closepreviewimage
<!-- UTSAPIJSON.closePreviewImage.description -->
<!-- UTSAPIJSON.closePreviewImage.param -->
<!-- UTSAPIJSON.closePreviewImage.returnValue -->
<!-- UTSAPIJSON.closePreviewImage.example -->
<!-- UTSAPIJSON.closePreviewImage.compatibility -->
<!-- UTSAPIJSON.closePreviewImage.tutorial -->
<!-- UTSAPIJSON.preview-image.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.showToast(options) @showtoast
<!-- UTSAPIJSON.showToast.description -->
<!-- UTSAPIJSON.showToast.param -->
<!-- UTSAPIJSON.showToast.returnValue -->
<!-- UTSAPIJSON.showToast.example -->
<!-- UTSAPIJSON.showToast.compatibility -->
<!-- UTSAPIJSON.showToast.tutorial -->
#### 注意事项 ####
+ `position` 参数`android`平台特别说明
如果没有设置 `position` 字段,`uni.showToast` 会采用应用弹窗方案,即弹窗与页面生命周期绑定。 页面关闭时,当前页面弹出的所有弹窗都会被自动取消。
如果设置了`position` 字段,`uni.showToast` 会采用系统弹窗方案,即弹窗与页面无绑定关系。 页面关闭后,弹出中的/等待弹出的`Toast`会继续展示。
系统弹窗在部分系统(比如 MIUI,Google)可能会有应用图标前缀。
系统弹窗在部分系统(比如 鸿蒙 4.0以上)可能不支持顶部和居中展示。
## uni.showLoading(options) @showloading
<!-- UTSAPIJSON.showLoading.description -->
<!-- UTSAPIJSON.showLoading.param -->
<!-- UTSAPIJSON.showLoading.returnValue -->
<!-- UTSAPIJSON.showLoading.example -->
<!-- UTSAPIJSON.showLoading.compatibility -->
<!-- UTSAPIJSON.showLoading.tutorial -->
## uni.showModal(options) @showmodal
<!-- UTSAPIJSON.showModal.description -->
<!-- UTSAPIJSON.showModal.param -->
<!-- UTSAPIJSON.showModal.returnValue -->
<!-- UTSAPIJSON.showModal.example -->
<!-- UTSAPIJSON.showModal.compatibility -->
<!-- UTSAPIJSON.showModal.tutorial -->
## uni.showActionSheet(options) @showactionsheet
<!-- UTSAPIJSON.showActionSheet.description -->
<!-- UTSAPIJSON.showActionSheet.param -->
<!-- UTSAPIJSON.showActionSheet.returnValue -->
<!-- UTSAPIJSON.showActionSheet.example -->
<!-- UTSAPIJSON.showActionSheet.compatibility -->
<!-- UTSAPIJSON.showActionSheet.tutorial -->
<!-- UTSAPIJSON.prompt.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## Bug & Tips@tips
- 在页面生命周期 onLoad 中调用以上弹窗 API 可能无法正常显示,暂时建议在页面生命周期 onReady 及之后再调用。此bug已于HBuilderX 3.97+修复
## uni.startPullDownRefresh(options?) @startpulldownrefresh
<!-- UTSAPIJSON.startPullDownRefresh.description -->
<!-- UTSAPIJSON.startPullDownRefresh.param -->
<!-- UTSAPIJSON.startPullDownRefresh.returnValue -->
<!-- UTSAPIJSON.startPullDownRefresh.compatibility -->
<!-- UTSAPIJSON.startPullDownRefresh.tutorial -->
## uni.stopPullDownRefresh() @stoppulldownrefresh
<!-- UTSAPIJSON.stopPullDownRefresh.description -->
使用:
1. 首先pages.json里配置了页面可下拉刷新`"enablePullDownRefresh": true`
2. 当用户下拉页面时触发页面生命周期`onPullDownRefresh`
3. 在合适的时机(如联网刷新数据结束),调用本API`uni.stopPullDownRefresh()`,结束下拉刷新状态
本API仅负责页面下拉刷新。如使用组件下拉刷新,另见scroll-view、list-view等组件的文档。
<!-- UTSAPIJSON.stopPullDownRefresh.param -->
<!-- UTSAPIJSON.stopPullDownRefresh.returnValue -->
<!-- UTSAPIJSON.stopPullDownRefresh.example -->
<!-- UTSAPIJSON.stopPullDownRefresh.compatibility -->
<!-- UTSAPIJSON.stopPullDownRefresh.tutorial -->
<!-- UTSAPIJSON.pull-down-refresh.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
# uni-push
uni-push是DCloud与合作伙伴个推共同推出的统一推送服务。用于从服务器端推送消息到客户端。
它包括在线推送、离线推送,聚合了Apple、华为、小米、OPPO、VIVO、魅族、荣耀(3.99+)、Google等多个手机厂商的推送通道。
若不使用服务器推送,仅想创建手机通知栏本地消息,也需要使用本模块的API。
它是一个云端一体的业务,涉及多份文档:
1. 业务介绍:对于未使用过uni-push的新用户,本文必读:[uni-push业务介绍](https://uniapp.dcloud.net.cn/unipush-v2.html)
2. 客户端API,即本文
3. 服务器API,[另见](https://uniapp.dcloud.net.cn/uniCloud/uni-cloud-push/api)
## uni.getPushClientId(options) @getpushclientid
<!-- UTSAPIJSON.getPushClientId.description -->
<!-- UTSAPIJSON.getPushClientId.param -->
<!-- UTSAPIJSON.getPushClientId.returnValue -->
<!-- UTSAPIJSON.getPushClientId.compatibility -->
<!-- UTSAPIJSON.getPushClientId.tutorial -->
## uni.onPushMessage(callback) @onpushmessage
<!-- UTSAPIJSON.onPushMessage.description -->
<!-- UTSAPIJSON.onPushMessage.param -->
<!-- UTSAPIJSON.onPushMessage.returnValue -->
<!-- UTSAPIJSON.onPushMessage.compatibility -->
<!-- UTSAPIJSON.onPushMessage.tutorial -->
### 注意事项
* 如果多次监听`onPushMessage`,那么事件也会多次触发,所以当不需要监听的时候需要`offPushMessage`
## uni.offPushMessage(callback) @offpushmessage
<!-- UTSAPIJSON.offPushMessage.description -->
<!-- UTSAPIJSON.offPushMessage.param -->
<!-- UTSAPIJSON.offPushMessage.returnValue -->
<!-- UTSAPIJSON.offPushMessage.compatibility -->
<!-- UTSAPIJSON.offPushMessage.tutorial -->
## uni.getChannelManager() @getchannelmanager
<!-- UTSAPIJSON.getChannelManager.description -->
<!-- UTSAPIJSON.getChannelManager.param -->
<!-- UTSAPIJSON.getChannelManager.returnValue -->
<!-- UTSAPIJSON.getChannelManager.compatibility -->
<!-- UTSAPIJSON.getChannelManager.tutorial -->
### 注意事项
* 由于各大厂商限制推送频次,当使用厂商离线推送的时,需要在不同品牌手机后台开通自分类权益,[限制数量说明](https://docs.getui.com/getui/mobile/vendor/qps/)
- [华为](https://developer.huawei.com/consumer/cn/doc/HMSCore-Guides/message-classification-0000001149358835)
- [小米](https://dev.mi.com/console/doc/detail?pId=2422)
- [oppo](https://open.oppomobile.com/new/developmentDoc/info?id=11227)
- [vivo](https://dev.vivo.com.cn/documentCenter/doc/359)
开通自分类权益后,需要客户端创建channel,因此客户端提供了`setPushChannel`来进行channel的创建,通过此Api来创建渠道进行推送。
客户端创建渠道成功后,即可通过云函数进行推送,[uni-push2服务端文档](https://uniapp.dcloud.net.cn/uniCloud/uni-cloud-push/api.html)
* 由于Android通知渠道的机制问题,一旦通知渠道建立,便不能修改此渠道的配置,即使删除渠道后再次创建同channelId名称的渠道,也不会改变原先渠道的配置(除非删除应用),最明显的现象就是铃声动态修改失败,比如调用`setPushChannel`时,第一次的设置参数是`{"channelId":"test","soundName":"pushsound"}` , 这时你想切换铃音,你的channelId就不能再叫test了,而应该为`{"channelId":"test2","soundName":"ring"}` ,此时会新建一个渠道。
## uni.createPushMessage(options) @createpushmessage
<!-- UTSAPIJSON.createPushMessage.description -->
<!-- UTSAPIJSON.createPushMessage.param -->
<!-- UTSAPIJSON.createPushMessage.returnValue -->
<!-- UTSAPIJSON.createPushMessage.compatibility -->
<!-- UTSAPIJSON.createPushMessage.tutorial -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## 示例代码
hello uni-push是可跑通、同时包含客户端和服务器完整流程的代码。[https://gitcode.net/dcloud/hello-uni-push](https://gitcode.net/dcloud/hello-uni-push)
在业务开通、配置正确的情况下,执行项目下的云函数,即可给客户端发送消息。
## 注意事项
* 关于隐私安全问题,由于在调用`getPushClientId`或者`onPushMessage`时,才会初始化个推SDK,所以开发者要确保弹出隐私框之前不调用此两项API。
* 关于图标的配置,需要创建[nativeResources](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-android.html#%E5%BA%94%E7%94%A8%E8%B5%84%E6%BA%90)目录,放置对应分辨率的图片资源即可 ,目录配置如下
```
├── nativeResources
│   └── android
│   └── res
│   ├── drawable-ldpi
│   │   ├── push.png // 分辨率要求48x48
│   │   └── push_small.png // 分辨率要求18x18
│   ├── drawable-mdpi
│   │   ├── push.png // 分辨率要求64x64
│   │   └── push_small.png // 分辨率要求24x24
│   ├── drawable-hdpi
│   │   ├── push.png // 分辨率要求96x96
│   │   └── push_small.png // 分辨率要求36x36
│   ├── drawable-xhdpi
│   │   ├── push.png // 分辨率要求128x128
│   │   └── push_small.png // 分辨率要求48x48
│   ├── drawable-xxhdpi
│   │   ├── push.png // 分辨率要求192x192
│   │   └── push_small.png // 分辨率要求72x72
│   ├── drawable-xxxhdpi
│   │   └── push_small.png // 分辨率要求96x96
│   └── raw
│   └── pushsound.mp3 // 声音文件, 自定义推送铃音时使用
```
* `setPushChannel`设置新建渠道时,`soundName`字段的值为nativeResources->android->res->raw中存放的音频文件名称,注意不要带文件的后缀,比如`pushsound.mp3`文件,例:
```
const channelManager = getChannelManager()
channelManager.setPushChannel({
channelId: "test1",
channelDesc: "test1 desc",
soundName: "pushsound"
})
```
* uni-app x 的push模块仅支持uni-push2,不再支持uni-push1。但这不意味着强绑uniCloud的付费行为。而是DCloud的所有云服务都将统一纳入到uniCloud体系管理,开发者在开通uni-push2后,也可以拿到mastersecret,然后在自己的服务器去直接连接个推服务器。
* uni-push是一个独立的模块,在标准基座中并不包含。开发push需要首先编写push相关代码,然后打包自定义基座,根据摇树规则,打出的自定义基座才会包含push模块。详见[摇树](../manifest.md#treeShaking)
* 创建本地通知栏,理论上可以和个推的服务无关。但目前也都包含在push模块里了。如果您不需要服务器推送,只需要本地创建通知栏,也需要打包push模块才行。
* 部分手机创建本地通知时,App如果在后台状态,点击通知消息并不会拉起App,原因是厂商增加了后台弹窗权限,需要用户手动打开此权限。
* 获取手机端app是否拥有push权限,请使用API [uni.getAppAuthorizeSetting](get-app-authorize-setting.md)
\ No newline at end of file
## uni.request(param) @request
<!-- UTSAPIJSON.request.description -->
<!-- UTSAPIJSON.request.param -->
<!-- UTSAPIJSON.request.returnValue -->
<!-- UTSAPIJSON.request.compatibility -->
<!-- UTSAPIJSON.request.tutorial -->
<!-- UTSAPIJSON.request.example -->
## 注意事项
* request 接口内部通过[特殊方式读取了泛型类型](../../uts/generics.md#使用限制),不支持传入动态的泛型:比如将外层方法的普通泛型参数传入 request。
* 如果使用泛型先创建RequestOptions实例,再传入uni.request(),此时请务必确保request要显式指定泛型,例:
```typescript
const options: RequestOptions<Person> = ...
uni.request<Person>(options)
```
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## uni.saveImageToPhotosAlbum(options) @saveimagetophotosalbum
<!-- UTSAPIJSON.saveImageToPhotosAlbum.description -->
<!-- UTSAPIJSON.saveImageToPhotosAlbum.param -->
<!-- UTSAPIJSON.saveImageToPhotosAlbum.returnValue -->
<!-- UTSAPIJSON.saveImageToPhotosAlbum.example -->
<!-- UTSAPIJSON.saveImageToPhotosAlbum.compatibility -->
<!-- UTSAPIJSON.saveImageToPhotosAlbum.tutorial -->
<!-- UTSAPIJSON.save-image-to-photos-album.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.setNavigationBarColor(options) @setnavigationbarcolor
<!-- UTSAPIJSON.setNavigationBarColor.description -->
即便pages.json里没有配置NavigationBar,如需修改状态栏的前景背景,也需要本API。
<!-- UTSAPIJSON.setNavigationBarColor.param -->
<!-- UTSAPIJSON.setNavigationBarColor.returnValue -->
<!-- UTSAPIJSON.setNavigationBarColor.example -->
<!-- UTSAPIJSON.setNavigationBarColor.compatibility -->
<!-- UTSAPIJSON.setNavigationBarColor.tutorial -->
<!-- UTSAPIJSON.set-navigation-bar-color.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.setNavigationBarTitle(options) @setnavigationbartitle
<!-- UTSAPIJSON.setNavigationBarTitle.description -->
<!-- UTSAPIJSON.setNavigationBarTitle.param -->
<!-- UTSAPIJSON.setNavigationBarTitle.returnValue -->
<!-- UTSAPIJSON.setNavigationBarTitle.compatibility -->
<!-- UTSAPIJSON.setNavigationBarTitle.tutorial -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.setTabBarBadge(options) @settabbarbadge
<!-- UTSAPIJSON.setTabBarBadge.description -->
<!-- UTSAPIJSON.setTabBarBadge.param -->
<!-- UTSAPIJSON.setTabBarBadge.returnValue -->
<!-- UTSAPIJSON.setTabBarBadge.example -->
<!-- UTSAPIJSON.setTabBarBadge.compatibility -->
<!-- UTSAPIJSON.setTabBarBadge.tutorial -->
## uni.removeTabBarBadge(options) @removetabbarbadge
<!-- UTSAPIJSON.removeTabBarBadge.description -->
<!-- UTSAPIJSON.removeTabBarBadge.param -->
<!-- UTSAPIJSON.removeTabBarBadge.returnValue -->
<!-- UTSAPIJSON.removeTabBarBadge.example -->
<!-- UTSAPIJSON.removeTabBarBadge.compatibility -->
<!-- UTSAPIJSON.removeTabBarBadge.tutorial -->
## uni.setTabBarItem(options) @settabbaritem
<!-- UTSAPIJSON.setTabBarItem.description -->
<!-- UTSAPIJSON.setTabBarItem.param -->
<!-- UTSAPIJSON.setTabBarItem.returnValue -->
<!-- UTSAPIJSON.setTabBarItem.example -->
<!-- UTSAPIJSON.setTabBarItem.compatibility -->
<!-- UTSAPIJSON.setTabBarItem.tutorial -->
## uni.setTabBarStyle(options) @settabbarstyle
<!-- UTSAPIJSON.setTabBarStyle.description -->
<!-- UTSAPIJSON.setTabBarStyle.param -->
<!-- UTSAPIJSON.setTabBarStyle.returnValue -->
<!-- UTSAPIJSON.setTabBarStyle.example -->
<!-- UTSAPIJSON.setTabBarStyle.compatibility -->
<!-- UTSAPIJSON.setTabBarStyle.tutorial -->
## uni.hideTabBar(options?) @hidetabbar
<!-- UTSAPIJSON.hideTabBar.description -->
<!-- UTSAPIJSON.hideTabBar.param -->
<!-- UTSAPIJSON.hideTabBar.returnValue -->
<!-- UTSAPIJSON.hideTabBar.example -->
<!-- UTSAPIJSON.hideTabBar.compatibility -->
<!-- UTSAPIJSON.hideTabBar.tutorial -->
## uni.showTabBar(options?) @showtabbar
<!-- UTSAPIJSON.showTabBar.description -->
<!-- UTSAPIJSON.showTabBar.param -->
<!-- UTSAPIJSON.showTabBar.returnValue -->
<!-- UTSAPIJSON.showTabBar.example -->
<!-- UTSAPIJSON.showTabBar.compatibility -->
<!-- UTSAPIJSON.showTabBar.tutorial -->
## uni.showTabBarRedDot(options) @showtabbarreddot
<!-- UTSAPIJSON.showTabBarRedDot.description -->
<!-- UTSAPIJSON.showTabBarRedDot.param -->
<!-- UTSAPIJSON.showTabBarRedDot.returnValue -->
<!-- UTSAPIJSON.showTabBarRedDot.example -->
<!-- UTSAPIJSON.showTabBarRedDot.compatibility -->
<!-- UTSAPIJSON.showTabBarRedDot.tutorial -->
## uni.hideTabBarRedDot(options) @hidetabbarreddot
<!-- UTSAPIJSON.hideTabBarRedDot.description -->
<!-- UTSAPIJSON.hideTabBarRedDot.param -->
<!-- UTSAPIJSON.hideTabBarRedDot.returnValue -->
<!-- UTSAPIJSON.hideTabBarRedDot.example -->
<!-- UTSAPIJSON.hideTabBarRedDot.compatibility -->
<!-- UTSAPIJSON.hideTabBarRedDot.tutorial -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## key-value本地数据存储
app、小程序、web,均提供了方便的key-value模式的本地数据存储,通过键值对的方式存取数据。
uni-app的Storage在不同端的实现不同:
- H5端为localStorage,浏览器限制5M大小,是缓存概念,可能会被清理
- App端为原生storage,无大小限制,不是缓存,是持久化的
- 各个小程序端为其自带的storage api,数据存储生命周期跟小程序本身一致,即除用户主动删除或超过一定时间被自动清理,否则数据都一直可用。
* 微信小程序单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
* 支付宝小程序单条数据转换成字符串后,字符串长度最大200*1024。同一个支付宝用户,同一个小程序缓存总上限为10MB。
* 百度小程序策略[详见](https://smartprogram.baidu.com/docs/develop/api/storage/save_process/)
* 抖音小程序策略[详见](https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/data-caching/tt-get-storage)
**注意**
- `uni-``uni_``dcloud-``dcloud_`为前缀的key,为系统保留关键前缀。如`uni_deviceId``uni_id_token`,请开发者为key命名时避开这些前缀。
- 非App平台清空Storage会导致uni.getSystemInfo获取到的deviceId改变
## uni.setStorage(options) @setstorage
<!-- UTSAPIJSON.setStorage.description -->
<!-- UTSAPIJSON.setStorage.param -->
<!-- UTSAPIJSON.setStorage.returnValue -->
<!-- UTSAPIJSON.setStorage.example -->
<!-- UTSAPIJSON.setStorage.compatibility -->
<!-- UTSAPIJSON.setStorage.tutorial -->
## uni.setStorageSync(key, data) @setstoragesync
<!-- UTSAPIJSON.setStorageSync.description -->
<!-- UTSAPIJSON.setStorageSync.param -->
<!-- UTSAPIJSON.setStorageSync.returnValue -->
<!-- UTSAPIJSON.setStorageSync.example -->
<!-- UTSAPIJSON.setStorageSync.compatibility -->
<!-- UTSAPIJSON.setStorageSync.tutorial -->
## uni.getStorage(options) @getstorage
<!-- UTSAPIJSON.getStorage.description -->
<!-- UTSAPIJSON.getStorage.param -->
<!-- UTSAPIJSON.getStorage.returnValue -->
<!-- UTSAPIJSON.getStorage.example -->
<!-- UTSAPIJSON.getStorage.compatibility -->
<!-- UTSAPIJSON.getStorage.tutorial -->
## uni.getStorageSync(key) @getstoragesync
<!-- UTSAPIJSON.getStorageSync.description -->
<!-- UTSAPIJSON.getStorageSync.param -->
<!-- UTSAPIJSON.getStorageSync.returnValue -->
<!-- UTSAPIJSON.getStorageSync.example -->
<!-- UTSAPIJSON.getStorageSync.compatibility -->
<!-- UTSAPIJSON.getStorageSync.tutorial -->
## uni.getStorageInfo(options) @getstorageinfo
<!-- UTSAPIJSON.getStorageInfo.description -->
<!-- UTSAPIJSON.getStorageInfo.param -->
<!-- UTSAPIJSON.getStorageInfo.returnValue -->
<!-- UTSAPIJSON.getStorageInfo.example -->
<!-- UTSAPIJSON.getStorageInfo.compatibility -->
<!-- UTSAPIJSON.getStorageInfo.tutorial -->
## uni.getStorageInfoSync() @getstorageinfosync
<!-- UTSAPIJSON.getStorageInfoSync.description -->
<!-- UTSAPIJSON.getStorageInfoSync.param -->
<!-- UTSAPIJSON.getStorageInfoSync.returnValue -->
<!-- UTSAPIJSON.getStorageInfoSync.example -->
<!-- UTSAPIJSON.getStorageInfoSync.compatibility -->
<!-- UTSAPIJSON.getStorageInfoSync.tutorial -->
## uni.removeStorage(options) @removestorage
<!-- UTSAPIJSON.removeStorage.description -->
<!-- UTSAPIJSON.removeStorage.param -->
<!-- UTSAPIJSON.removeStorage.returnValue -->
<!-- UTSAPIJSON.removeStorage.example -->
<!-- UTSAPIJSON.removeStorage.compatibility -->
<!-- UTSAPIJSON.removeStorage.tutorial -->
## uni.removeStorageSync(key) @removestoragesync
<!-- UTSAPIJSON.removeStorageSync.description -->
<!-- UTSAPIJSON.removeStorageSync.param -->
<!-- UTSAPIJSON.removeStorageSync.returnValue -->
<!-- UTSAPIJSON.removeStorageSync.example -->
<!-- UTSAPIJSON.removeStorageSync.compatibility -->
<!-- UTSAPIJSON.removeStorageSync.tutorial -->
## uni.clearStorage(option?) @clearstorage
<!-- UTSAPIJSON.clearStorage.description -->
<!-- UTSAPIJSON.clearStorage.param -->
<!-- UTSAPIJSON.clearStorage.returnValue -->
<!-- UTSAPIJSON.clearStorage.example -->
<!-- UTSAPIJSON.clearStorage.compatibility -->
<!-- UTSAPIJSON.clearStorage.tutorial -->
## uni.clearStorageSync() @clearstoragesync
<!-- UTSAPIJSON.clearStorageSync.description -->
<!-- UTSAPIJSON.clearStorageSync.param -->
<!-- UTSAPIJSON.clearStorageSync.returnValue -->
<!-- UTSAPIJSON.clearStorageSync.example -->
<!-- UTSAPIJSON.clearStorageSync.compatibility -->
<!-- UTSAPIJSON.clearStorageSync.tutorial -->
<!-- UTSAPIJSON.storage.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## 概述
截止到目前,uni-app x下的uniCloud还不支持:
- 暂不支持schema2code
- 暂不支持安全网络
- 暂不支持泛型
- 暂不支持pages.json中的uniIdRouter
- 本文档未列举的API均不支持
**兼容说明**
- `HBuilderX 3.9+`支持阿里云,`3.91+`支持腾讯云,`3.98+`支持支付宝小程序云
- `HBuilderX 3.91+`支持clientDB,但不支持getOne和multiSend
<!-- UTSUNICLOUDAPIJSON.uniCloud_props.description -->
<!-- UTSUNICLOUDAPIJSON.uniCloud_props.param -->
<!-- UTSUNICLOUDAPIJSON.uniCloud_props.returnValue -->
<!-- UTSUNICLOUDAPIJSON.uniCloud_props.compatibility -->
<!-- UTSUNICLOUDAPIJSON.uniCloud_props.tutorial -->
\ No newline at end of file
## databaseForJQL() @databaseforjql
**和uni-app项目接口差异**
- uni-app x项目内数据库的客户端接口仅支持databaseForJQL不再支持database方法。
- action云函数因为安全问题已经不再推荐使用。开发者应使用[数据库触发器](https://uniapp.dcloud.net.cn/uniCloud/jql-schema-ext.html)来实现相关功能。
- 暂不支持multiSend
<!-- UTSUNICLOUDAPIJSON.databaseForJQL.description -->
<!-- UTSUNICLOUDAPIJSON.databaseForJQL.param -->
<!-- UTSUNICLOUDAPIJSON.databaseForJQL.returnValue -->
<!-- UTSUNICLOUDAPIJSON.databaseForJQL.compatibility -->
<!-- UTSUNICLOUDAPIJSON.databaseForJQL.tutorial -->
<!-- UTSUNICLOUDAPIJSON.unicloud-database.example -->
## callFunction(options) @callfunction
<!-- UTSUNICLOUDAPIJSON.callFunction.description -->
<!-- UTSUNICLOUDAPIJSON.callFunction.param -->
<!-- UTSUNICLOUDAPIJSON.callFunction.returnValue -->
<!-- UTSUNICLOUDAPIJSON.callFunction.compatibility -->
<!-- UTSUNICLOUDAPIJSON.callFunction.tutorial -->
<!-- UTSUNICLOUDAPIJSON.unicloud-call-function.example -->
## importObject(objectName, options?) @importobject
<!-- UTSUNICLOUDAPIJSON.importObject.description -->
<!-- UTSUNICLOUDAPIJSON.importObject.param -->
<!-- UTSUNICLOUDAPIJSON.importObject.returnValue -->
<!-- UTSUNICLOUDAPIJSON.importObject.compatibility -->
<!-- UTSUNICLOUDAPIJSON.importObject.tutorial -->
### uni-app x内使用云对象的特殊说明@strictly-typed-object
由于强类型语言的限制,uni-app-x在编译时需要读取本地云对象导出的方法列表生成客户端对象。
- 请确保调用的云对象在本地包含导出的方法。
- 请确保本地工程的云对象的方法是正确的。
- 如由于云函数加密等因素导致`index.obj.js`无法被正确解析,请在云对象目录创建`index.obj.d.ts`声明云对象内包含的方法。`index.obj.d.ts`示例代码如下:
```ts
// interface.d.ts
type AnyFunction = (...args: any[]) => any;
declare const add: AnyFunction
declare const update: AnyFunction
declare const deleteRecord: AnyFunction
export { // 上面的写法可以自己调整,仅需保证export内包含所有方法即可
add,
update
deleteRecord as remove
}
```
<!-- UTSUNICLOUDAPIJSON.unicloud-import-object.example -->
\ No newline at end of file
## uploadFile(options) @uploadfile
<!-- UTSUNICLOUDAPIJSON.uploadFile.description -->
<!-- UTSUNICLOUDAPIJSON.uploadFile.param -->
<!-- UTSUNICLOUDAPIJSON.uploadFile.returnValue -->
<!-- UTSUNICLOUDAPIJSON.uploadFile.compatibility -->
<!-- UTSUNICLOUDAPIJSON.uploadFile.tutorial -->
<!-- UTSUNICLOUDAPIJSON.uploadFile.example -->
## chooseAndUploadFile(options) @chooseanduploadfile
<!-- UTSUNICLOUDAPIJSON.chooseAndUploadFile.description -->
<!-- UTSUNICLOUDAPIJSON.chooseAndUploadFile.param -->
<!-- UTSUNICLOUDAPIJSON.chooseAndUploadFile.returnValue -->
<!-- UTSUNICLOUDAPIJSON.chooseAndUploadFile.compatibility -->
<!-- UTSUNICLOUDAPIJSON.chooseAndUploadFile.tutorial -->
<!-- UTSUNICLOUDAPIJSON.chooseAndUploadFile.example -->
## getTempFileURL(options) @gettempfileurl
<!-- UTSUNICLOUDAPIJSON.getTempFileURL.description -->
<!-- UTSUNICLOUDAPIJSON.getTempFileURL.param -->
<!-- UTSUNICLOUDAPIJSON.getTempFileURL.returnValue -->
<!-- UTSUNICLOUDAPIJSON.getTempFileURL.compatibility -->
<!-- UTSUNICLOUDAPIJSON.getTempFileURL.tutorial -->
<!-- UTSUNICLOUDAPIJSON.unicloud-file-api.example -->
## onResponse(callback) @onresponse
<!-- UTSUNICLOUDAPIJSON.onResponse.description -->
<!-- UTSUNICLOUDAPIJSON.onResponse.param -->
<!-- UTSUNICLOUDAPIJSON.onResponse.returnValue -->
<!-- UTSUNICLOUDAPIJSON.onResponse.compatibility -->
<!-- UTSUNICLOUDAPIJSON.onResponse.tutorial -->
## offResponse(callback) @offresponse
<!-- UTSUNICLOUDAPIJSON.offResponse.description -->
<!-- UTSUNICLOUDAPIJSON.offResponse.param -->
<!-- UTSUNICLOUDAPIJSON.offResponse.returnValue -->
<!-- UTSUNICLOUDAPIJSON.offResponse.compatibility -->
<!-- UTSUNICLOUDAPIJSON.offResponse.tutorial -->
## onRefreshToken(callback) @onrefreshtoken
<!-- UTSUNICLOUDAPIJSON.onRefreshToken.description -->
<!-- UTSUNICLOUDAPIJSON.onRefreshToken.param -->
<!-- UTSUNICLOUDAPIJSON.onRefreshToken.returnValue -->
<!-- UTSUNICLOUDAPIJSON.onRefreshToken.compatibility -->
<!-- UTSUNICLOUDAPIJSON.onRefreshToken.tutorial -->
## offRefreshToken(callback) @offrefreshtoken
<!-- UTSUNICLOUDAPIJSON.offRefreshToken.description -->
<!-- UTSUNICLOUDAPIJSON.offRefreshToken.param -->
<!-- UTSUNICLOUDAPIJSON.offRefreshToken.returnValue -->
<!-- UTSUNICLOUDAPIJSON.offRefreshToken.compatibility -->
<!-- UTSUNICLOUDAPIJSON.offRefreshToken.tutorial -->
## getCurrentUserInfo() @getcurrentuserinfo
<!-- UTSUNICLOUDAPIJSON.getCurrentUserInfo.description -->
<!-- UTSUNICLOUDAPIJSON.getCurrentUserInfo.param -->
<!-- UTSUNICLOUDAPIJSON.getCurrentUserInfo.returnValue -->
<!-- UTSUNICLOUDAPIJSON.getCurrentUserInfo.compatibility -->
<!-- UTSUNICLOUDAPIJSON.getCurrentUserInfo.tutorial -->
\ No newline at end of file
## uni.uploadFile(options) @uploadfile
<!-- UTSAPIJSON.uploadFile.description -->
<!-- UTSAPIJSON.uploadFile.param -->
<!-- UTSAPIJSON.uploadFile.returnValue -->
<!-- UTSAPIJSON.uploadFile.example -->
<!-- UTSAPIJSON.uploadFile.compatibility -->
<!-- UTSAPIJSON.uploadFile.tutorial -->
<!-- UTSAPIJSON.upload-file.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.connectSocket(options) @connectsocket
<!-- UTSAPIJSON.connectSocket.description -->
<!-- UTSAPIJSON.connectSocket.param -->
<!-- UTSAPIJSON.connectSocket.returnValue -->
<!-- UTSAPIJSON.connectSocket.example -->
<!-- UTSAPIJSON.connectSocket.compatibility -->
<!-- UTSAPIJSON.connectSocket.tutorial -->
## uni.onSocketOpen(options) @onsocketopen
<!-- UTSAPIJSON.onSocketOpen.description -->
<!-- UTSAPIJSON.onSocketOpen.param -->
<!-- UTSAPIJSON.onSocketOpen.returnValue -->
<!-- UTSAPIJSON.onSocketOpen.example -->
<!-- UTSAPIJSON.onSocketOpen.compatibility -->
<!-- UTSAPIJSON.onSocketOpen.tutorial -->
## uni.onSocketError(callback) @onsocketerror
<!-- UTSAPIJSON.onSocketError.description -->
<!-- UTSAPIJSON.onSocketError.param -->
<!-- UTSAPIJSON.onSocketError.returnValue -->
<!-- UTSAPIJSON.onSocketError.example -->
<!-- UTSAPIJSON.onSocketError.compatibility -->
<!-- UTSAPIJSON.onSocketError.tutorial -->
## uni.sendSocketMessage(options) @sendsocketmessage
<!-- UTSAPIJSON.sendSocketMessage.description -->
<!-- UTSAPIJSON.sendSocketMessage.param -->
<!-- UTSAPIJSON.sendSocketMessage.returnValue -->
<!-- UTSAPIJSON.sendSocketMessage.example -->
<!-- UTSAPIJSON.sendSocketMessage.compatibility -->
<!-- UTSAPIJSON.sendSocketMessage.tutorial -->
## 注意事项
* 出于性能的权衡,在底层实现上发送队列占用的内存不能超过16M,一旦超过将导致连接被关闭。
## uni.onSocketMessage(callback) @onsocketmessage
<!-- UTSAPIJSON.onSocketMessage.description -->
<!-- UTSAPIJSON.onSocketMessage.param -->
<!-- UTSAPIJSON.onSocketMessage.returnValue -->
<!-- UTSAPIJSON.onSocketMessage.example -->
<!-- UTSAPIJSON.onSocketMessage.compatibility -->
<!-- UTSAPIJSON.onSocketMessage.tutorial -->
## uni.closeSocket(options) @closesocket
<!-- UTSAPIJSON.closeSocket.description -->
<!-- UTSAPIJSON.closeSocket.param -->
<!-- UTSAPIJSON.closeSocket.returnValue -->
<!-- UTSAPIJSON.closeSocket.example -->
<!-- UTSAPIJSON.closeSocket.compatibility -->
<!-- UTSAPIJSON.closeSocket.tutorial -->
## uni.onSocketClose(callback) @onsocketclose
<!-- UTSAPIJSON.onSocketClose.description -->
<!-- UTSAPIJSON.onSocketClose.param -->
<!-- UTSAPIJSON.onSocketClose.returnValue -->
<!-- UTSAPIJSON.onSocketClose.example -->
<!-- UTSAPIJSON.onSocketClose.compatibility -->
<!-- UTSAPIJSON.onSocketClose.tutorial -->
<!-- UTSAPIJSON.websocket-global.example -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
## uni.connectSocket(options) @connectsocket
<!-- UTSAPIJSON.connectSocket.description -->
<!-- UTSAPIJSON.connectSocket.param -->
<!-- UTSAPIJSON.connectSocket.returnValue -->
<!-- UTSAPIJSON.connectSocket.example -->
<!-- UTSAPIJSON.connectSocket.compatibility -->
<!-- UTSAPIJSON.connectSocket.tutorial -->
## uni.onSocketOpen(options) @onsocketopen
<!-- UTSAPIJSON.onSocketOpen.description -->
<!-- UTSAPIJSON.onSocketOpen.param -->
<!-- UTSAPIJSON.onSocketOpen.returnValue -->
<!-- UTSAPIJSON.onSocketOpen.example -->
<!-- UTSAPIJSON.onSocketOpen.compatibility -->
<!-- UTSAPIJSON.onSocketOpen.tutorial -->
## uni.onSocketError(callback) @onsocketerror
<!-- UTSAPIJSON.onSocketError.description -->
<!-- UTSAPIJSON.onSocketError.param -->
<!-- UTSAPIJSON.onSocketError.returnValue -->
<!-- UTSAPIJSON.onSocketError.example -->
<!-- UTSAPIJSON.onSocketError.compatibility -->
<!-- UTSAPIJSON.onSocketError.tutorial -->
## uni.sendSocketMessage(options) @sendsocketmessage
<!-- UTSAPIJSON.sendSocketMessage.description -->
<!-- UTSAPIJSON.sendSocketMessage.param -->
<!-- UTSAPIJSON.sendSocketMessage.returnValue -->
<!-- UTSAPIJSON.sendSocketMessage.example -->
<!-- UTSAPIJSON.sendSocketMessage.compatibility -->
<!-- UTSAPIJSON.sendSocketMessage.tutorial -->
## uni.onSocketMessage(callback) @onsocketmessage
<!-- UTSAPIJSON.onSocketMessage.description -->
<!-- UTSAPIJSON.onSocketMessage.param -->
<!-- UTSAPIJSON.onSocketMessage.returnValue -->
<!-- UTSAPIJSON.onSocketMessage.example -->
<!-- UTSAPIJSON.onSocketMessage.compatibility -->
<!-- UTSAPIJSON.onSocketMessage.tutorial -->
## uni.closeSocket(options) @closesocket
<!-- UTSAPIJSON.closeSocket.description -->
<!-- UTSAPIJSON.closeSocket.param -->
<!-- UTSAPIJSON.closeSocket.returnValue -->
<!-- UTSAPIJSON.closeSocket.example -->
<!-- UTSAPIJSON.closeSocket.compatibility -->
<!-- UTSAPIJSON.closeSocket.tutorial -->
## uni.onSocketClose(callback) @onsocketclose
<!-- UTSAPIJSON.onSocketClose.description -->
<!-- UTSAPIJSON.onSocketClose.param -->
<!-- UTSAPIJSON.onSocketClose.returnValue -->
<!-- UTSAPIJSON.onSocketClose.example -->
<!-- UTSAPIJSON.onSocketClose.compatibility -->
<!-- UTSAPIJSON.onSocketClose.tutorial -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
## uni.startWifi(option) @startwifi
<!-- UTSAPIJSON.startWifi.description -->
<!-- UTSAPIJSON.startWifi.param -->
<!-- UTSAPIJSON.startWifi.returnValue -->
<!-- UTSAPIJSON.startWifi.compatibility -->
<!-- UTSAPIJSON.startWifi.tutorial -->
## uni.stopWifi(option) @stopwifi
<!-- UTSAPIJSON.stopWifi.description -->
<!-- UTSAPIJSON.stopWifi.param -->
<!-- UTSAPIJSON.stopWifi.returnValue -->
<!-- UTSAPIJSON.stopWifi.compatibility -->
<!-- UTSAPIJSON.stopWifi.tutorial -->
## uni.connectWifi(option) @connectwifi
<!-- UTSAPIJSON.connectWifi.description -->
<!-- UTSAPIJSON.connectWifi.param -->
<!-- UTSAPIJSON.connectWifi.returnValue -->
<!-- UTSAPIJSON.connectWifi.compatibility -->
<!-- UTSAPIJSON.connectWifi.tutorial -->
## uni.getWifiList(option) @getwifilist
<!-- UTSAPIJSON.getWifiList.description -->
<!-- UTSAPIJSON.getWifiList.param -->
<!-- UTSAPIJSON.getWifiList.returnValue -->
<!-- UTSAPIJSON.getWifiList.compatibility -->
<!-- UTSAPIJSON.getWifiList.tutorial -->
## uni.onGetWifiList(UniWifiCallback) @ongetwifilist
<!-- UTSAPIJSON.onGetWifiList.description -->
<!-- UTSAPIJSON.onGetWifiList.param -->
<!-- UTSAPIJSON.onGetWifiList.returnValue -->
<!-- UTSAPIJSON.onGetWifiList.compatibility -->
<!-- UTSAPIJSON.onGetWifiList.tutorial -->
## uni.offGetWifiList(UniWifiCallback) @offgetwifilist
<!-- UTSAPIJSON.offGetWifiList.description -->
<!-- UTSAPIJSON.offGetWifiList.param -->
<!-- UTSAPIJSON.offGetWifiList.returnValue -->
<!-- UTSAPIJSON.offGetWifiList.compatibility -->
<!-- UTSAPIJSON.offGetWifiList.tutorial -->
## uni.getConnectedWifi(option) @getconnectedwifi
<!-- UTSAPIJSON.getConnectedWifi.description -->
<!-- UTSAPIJSON.getConnectedWifi.param -->
<!-- UTSAPIJSON.getConnectedWifi.returnValue -->
<!-- UTSAPIJSON.getConnectedWifi.compatibility -->
<!-- UTSAPIJSON.getConnectedWifi.tutorial -->
## uni.onWifiConnected(UniWifiCallback) @onwificonnected
<!-- UTSAPIJSON.onWifiConnected.description -->
<!-- UTSAPIJSON.onWifiConnected.param -->
<!-- UTSAPIJSON.onWifiConnected.returnValue -->
<!-- UTSAPIJSON.onWifiConnected.compatibility -->
<!-- UTSAPIJSON.onWifiConnected.tutorial -->
## uni.onWifiConnectedWithPartialInfo(UniWifiCallback) @onwificonnectedwithpartialinfo
<!-- UTSAPIJSON.onWifiConnectedWithPartialInfo.description -->
<!-- UTSAPIJSON.onWifiConnectedWithPartialInfo.param -->
<!-- UTSAPIJSON.onWifiConnectedWithPartialInfo.returnValue -->
<!-- UTSAPIJSON.onWifiConnectedWithPartialInfo.compatibility -->
<!-- UTSAPIJSON.onWifiConnectedWithPartialInfo.tutorial -->
## uni.offWifiConnected(callback?) @offwificonnected
<!-- UTSAPIJSON.offWifiConnected.description -->
<!-- UTSAPIJSON.offWifiConnected.param -->
<!-- UTSAPIJSON.offWifiConnected.returnValue -->
<!-- UTSAPIJSON.offWifiConnected.compatibility -->
<!-- UTSAPIJSON.offWifiConnected.tutorial -->
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
* [pages.json](pagesjson.md)
* [main.uts](https://uniapp.dcloud.net.cn/collocation/main.html)
* [app.uvue](app.md)
* manifest.json
* [概述](manifest.md)
* [模块配置](manifest-modules.md)
* [启动界面](manifest-splashscreen.md)
* [AndroidManifest.xml](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-android.html)
* [uni.scss](https://uniapp.dcloud.net.cn/collocation/uni-scss.html)
\ No newline at end of file
# App.uvue
`App.uvue`是uni-app-x的主组件。
所有页面都是在`App.uvue`下进行切换的,是应用入口文件。但`App.uvue`本身不是页面,这里不能编写视图元素,也就是没有`<template>`
这个文件的作用包括:监听应用生命周期、配置全局样式、配置全局的存储globalData
应用生命周期仅可在`App.uvue`中监听,在页面监听无效。
## 应用生命周期@applifecycle
`uni-app-x` 支持如下应用生命周期函数:
|函数名|说明|平台兼容|
|:-|:-|:-|
|onLaunch|当`uni-app-x` 初始化完成时触发(全局只触发一次),参数为应用启动参数,同 [uni.getLaunchOptionsSync](https://uniapp.dcloud.net.cn/api/getLaunchOptionsSync.html#getlaunchoptionssync) 的返回值||
|onShow|当 `uni-app-x` 启动,或从后台进入前台显示,参数为应用启动参数,同 [uni.getLaunchOptionsSync](https://uniapp.dcloud.net.cn/api/getLaunchOptionsSync.html#getlaunchoptionssync) 的返回值||
|onHide|当 `uni-app-x` 从前台进入后台||
|onLastPageBackPress|最后一个页面按下Android back键,常用于自定义退出|app-uvue-android 3.9+|
|onExit|监听应用退出|app-uvue-android 3.9+|
**示例代码**
```html
<script lang="uts">
// 只能在App.vue里监听应用的生命周期
export default {
onLaunch: function(options) {
console.log('App Launch')
console.log('应用启动路径:', options.path)
},
onShow: function(options) {
console.log('App Show')
console.log('应用启动路径:', options.path)
},
onHide: function() {
console.log('App Hide')
},
onLastPageBackPress: function () {
console.log('App LastPageBackPress')
}
}
</script>
```
**注意**
- **应用生命周期仅可在`App.uvue`中监听,在其它页面监听无效**
- 应用启动参数,可以在API `uni.getLaunchOptionsSync`获取,[详见](https://uniapp.dcloud.net.cn/api/getLaunchOptionsSync.html#getlaunchoptionssync)
<!-- - onPageNotFound 页面实际上已经打开了(比如通过分享卡片、小程序码)且发现页面不存在,才会触发,api 跳转不存在的页面不会触发(如 uni.navigateTo) -->
## globalData
小程序有 globalData,这是一种简单的全局变量机制。这套机制在 uni-app-x 里也可以使用,并且全端通用。
当然 vue 框架的全局变量,另有其他方式定义。
**以下是 App.uvue 中定义globalData的相关配置:**
```ts
<script lang="uts">
export default {
globalData: {
str: 'global data str',
num: 123,
bool: true
}
}
</script>
```
页面或组件中通过 `getApp().globalData` 访问。
```ts
<script lang="uts">
export default {
methods: {
getGlobalData() {
const app = getApp()
this.globalDataStr = app.globalData.str
this.globalDataNum = app.globalData.num
this.globalDataBool = app.globalData.bool
}
}
}
</script>
```
**注意:** `uni-app x``globalData` 的数据结构与类型通过 `App.uvue` 中的 `globalData` 初始值定义,后续只能读取或修改,不能新增或删除。
globalData是简单的全局变量,其他状态管理方式,可参考文档[全局变量和状态管理](/uni-app-x/tutorial/store.md)
## 全局样式
`App.uvue`中,可以定义一些全局通用样式,例如需要加一个通用的背景色,首屏页面渲染的动画等都可以写在App.uvue中。
# modules
## 模块的摇树@treeShaking
uni-app x的Android基础库体积是7M,打包后的apk体积是基础库的体积加上开发者的代码及代码引用的模块的体积。有些模块涉及so库,覆盖的cpu指令越多,包体积越大。
在uni-app js引擎版中,内置模块如video,是开发者在manifest.json中手动勾选配置的。
但在uni-app x中,不需要手动配置。
HBuilderX3.93版本起,编译器支持扫描代码,摇树treeShaking,自动引入或剔除不需要的内置模块。
如应用中没有使用video组件相关功能,将不再包含video内置模块,减少安装包体积。
**摇树注意事项:**
当你打包自定义基座时,如果你的工程代码没有使用video、定位、相册、摄像头等涉及三方sdk或敏感权限的api,打出的自定义基座包就不会包含这些组件和api的功能,那么在这些自定义基座上运行时,调用相关的组件和api就会报错。\
此时您需要在工程中写相关的代码,如引用video组件或调用定位api,保存代码后重新打包自定义基座,才会包含相关模块。
您在工程中下载的ext api、三方uts插件也同理,没有引用就不会打进去。
### App端支持摇树的内置模块列表@utsmodules
- uni-network
网络请求(文件上传/下载)模块,包括API:[uni.downloadFile](./api/download-file.md)[uni.request](./api/request.md)[uni.uploadFile](./api/upload-file.md)
依赖的模块:无
- uni-getLocation-system
系统定位模块,包括API:[uni.getLocation](./api/get-location.md)
依赖的模块:无
- uni-video
[video视频组件](./component/video.md)模块,包括内置组件:[video](./component/video.md);包括API:[uni.createVideoContext](./api/create-video-context.md)
- uni-media
多媒体相关API模块,包括API:[uni.chooseImage](./api/choose-image.md)[uni.previewImage](./api/preview-image.md)[uni.saveImageToPhotosAlbum](./api/save-image-to-photos-album.md)
依赖的模块:无
- uni-cloud-client
调用uniCloud[云函数/云对象](../uniCloud/cf-functions.md)模块,包括API:[uniCloud.importObject](../uniCloud/cloud-obj.md#%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%B0%83%E7%94%A8)[uniCloud.callFunction](../uniCloud/cf-callfunction.md#callfunction%E6%96%B9%E6%B3%95)
依赖的模块:uni-media、uni-network
- uni-push
[uni-push统一推送](../unipush-v2.md)模块(`HBuilderX3.97+`),包括API:[uni.createPushMessage](../api/plugins/push.md#createpushmessage)[uni.getPushClientId](../api/plugins/push.md#getpushclientid)[uni.offPushMessage](../api/plugins/push.md#offpushmessage)[uni.onPushMessage](../api/plugins/push.md#onpushmessage)
依赖的模块:无
- uni-facialRecognitionVerify
[uni实人认证](../uniCloud/frv/intro.md)模块,包括API:[uni.getFacialRecognitionMetaInfo](../api/plugins/facialRecognitionVerify.md#getfacialrecognitionmetainfo)[uni.startFacialRecognitionVerify](../api/plugins/facialRecognitionVerify.md#startfacialrecognitionverify)
依赖的模块:无
再次强调,以上模块不属于ext组件或api,是内置模块。但如果你的代码中没有使用这些组件和api,打正式包或自定义基座时会被摇掉。
## uni-AD广告模块
HBuilderX3.99版本起,uni-app x 支持 uni-AD 开屏广告。
uni-AD 开屏广告作为一个独立的模块,不需要额外的API,应用启动时会自动拉取并展示开屏广告。由于开屏广告的特殊性,也导致uni-AD广告模块无法参与摇树。需要开发者打包时手动在 manifest.json 中添加广告配置。
uni-AD 开屏广告打包时需要在 manifest.json 中的 app->distribute->modules 节点下添加 uni-ad 节点。目前支持的广告平台有:腾讯优量汇广告联盟(gdt)、穿山甲GroMore(gm)、百度百青藤广告联盟(bd)、Sigmob广告联盟(sgm)、快手广告联盟(ks)。具体配置可参考下面配置:
```
modules:{
"uni-ad":{
"ks":{},
"gdt":{},
"bd":{},
"sgm":{},
"gm":{}
}
}
```
App启动时,系统加载应用渲染首页需要一定的时间,为了避免用户等待,手机操作系统提供了特殊的启动界面设计,让用户先看到一个简单的界面,等应用加载完成后正式进入应用首页。
这个界面,即被称为启动界面,也成称为 splash 或 lauch screen。
>HBuilderX3.99+版本支持App启动界面配置
### Android平台启动界面配置
打开项目的manifest.json文件,在“App启动界面配置”中的“Android启动界面设置”项下配置各设备分辨率启动图:
![](http://dcloud-chjh-native.oss-cn-hangzhou.aliyuncs.com/uni-app-x/doc/splash/splash_screen_android_1.png)
> 提示:启动界面设置需提交云端打包后才能生效
#### Android平台splash关闭时机
splash关闭时机可控制,打开项目的manifest.json文件,选择源码视图,在app->splashScreen节点下设置autoClose值域,控制splash关闭时机,默认onShow
**autoClose取值范围:**
|值域|说明|
|--|--|
|onShow|首页页面生命周期触发onShow时关闭splash|
|onReady|首页页面生命周期触发onReady时关闭splash|
配置示例:
```
"app" : {
"splashScreen" : {
"autoClose" : "onReady"
}
}
```
#### Android平台splash注意事项
1. splash关闭时机中描述的`首页`,指的是第一个真正显示的页面,如项目中pages.json第一个页面A在onLoad生命周期被关闭重新跳转了一个新页面B并显示,则B页面就是`首页`,原因是显示的是页面B,A页面并未显示,
如果是在页面A的onShow或更晚的生命周期关闭在跳转或直接跳转,则页面A是`首页`,因为页面A已经显示符合第一个真正显示的页面。
2. 应用冷启动与热启动的splash展示时间是有区别的。应用冷启动指首次启动或被kill掉进程后的启动,冷启动时初始化环境,数据加载等会占用一些启动时间,所以splash展示时间长一些。热启动指应用已启动后未kill进程再次的启动,由于不会再初始化环境,加载数据等操作,所以相对启动时间较少,splash展示时间也会缩短。
#### Android平台使用.9.png启动图@9png
目前HBuilderX中仅定义几种标准分辨率的启动图配置,而实际上存在很多不同分辨率的手机,导致启动图在一些不常见的设备会进行拉伸或压缩引起变形,Android平台为了解决此问题就出现了可以适配各种尺寸的一种图片格式“.9.png”。这是一种特殊的图片格式,它可以指定特定的区域进行拉伸而不失真。
**使用.9.png的优点**
1. 避免在非标准分辨率手机上缩放变形
2. 可以只配置1张或多张图片适配更多分辨率,减少apk的体积(推荐至少配置1080P高分屏启动图片)
**.9.png图片和普通png图片的差异**
1. .9.png图片和一般图片的区别在于.9.png图片有四条黑边,而一般的图片没有,这四条黑边就是用来拉伸和指定显示位置的
2. 使用.9.png图片后,整个图片应该是包裹着你想要显示的内容的,而没有使用的话整个图片将会被拉伸
**制作.9.png图片**
1. 在Android sdk目录下的tools目录下,有一个叫做draw9patch.bat的文件,双击打开就可以使用(最新android SDK该文件已经不存在,若电脑不没有安装android studio,可下载附件工具编辑.9.png图片)
2. 使用android studio,因为android studio已经集成.9.png制作工具,只需选中需要生成的png文件,然后右键,点击create 9-patch file 选项
详细制作步骤可参考链接:[Android中.9图片的含义及制作教程](https://www.jianshu.com/p/3fd048644e3f?tdsourcetag=s_pctim_aiomsg)
可以使用在线.9.png生成工具:[http://inloop.github.io/shadow4android/](http://inloop.github.io/shadow4android/)
**.9.png配置使用**
打开项目的manifest.json文件,在“App启动界面配置”中的“Android启动界面设置”项下,在各分辨率启动图设置框选择需要使用的.9.png图片(图片尺寸请按照提示尺寸对应上传),保存后提交云端打包即可。
> 不同尺寸的启动图是为了适配不同分辨率的手机,所以提交打包时请务必上传不同尺寸的启动图,切忌上传多张同尺寸启动图
可以参考开发者在[插件市场](https://ext.dcloud.net.cn/search?q=.9)做好的.9样例工程
# manifest.json
`manifest.json` 是 uni-app x 项目的配置文件,用于设置应用的名称、版本、图标等信息。在 HBuilderX 中创建项目时此文件保存在根目录。
uni-app x 目前不支持配置splash图,因uni-app x打包后启动速度非常快,可以自己做一个简单的uvue页面来当做splash。
uni-app x 不再提供内置模块选择,而是提供了摇树机制自动选择内置模块,具体[见下](#treeShaking)
## 配置项列表
<!-- MANIFESTJSON.manifest.description -->
<!-- MANIFESTJSON.manifest.table -->
**注意**
- `appid` 由 DCloud 云端分配,主要用于 DCloud 相关的云服务,请勿自行修改。[详见](https://ask.dcloud.net.cn/article/35907)
- `uni-app-x` 节点必须存在,它是一个项目是否是 uni-app x项目的核心标识。
* 缺少该节点时,HBuilderX 会把项目识别为 uni-app js引擎版项目(方形项目图标)。
* 含有该节点时,HBuilderX中的项目图标是圆形的。
### UNI-APP-X配置 @manifest-uni-app-x
<!-- MANIFESTJSON.manifest_uni-app-x.description -->
<!-- MANIFESTJSON.manifest_uni-app-x.table -->
### APP配置 @manifest-app
<!-- MANIFESTJSON.manifest_app.description -->
<!-- MANIFESTJSON.manifest_app.table -->
#### Android权限配置@permissions
uni-app x 的权限配置,移入了[AndroidManifest.xml](../tutorial/app-nativeresource-android.md#permissions)中。
使用[uni内置模块](#utsmodules)时,云端打包会自动添加模块需要的Android权限,不需要在[AndroidManifest.xml](../tutorial/app-nativeresource-android.md#permissions)中配置。
HBuilderX3.97+版本标准基座已经包含了所有Android权限,在 uvue 页面中直接通过 uts 调用需要权限的 Android 系统 API 时,使用标准基座真机运行可直接通过[UTSAndroid.requestSystemPermission](../uts/utsandroid.md#requestSystemPermission)申请;使用自定义基座则需要在项目的[AndroidManifest.xml](../tutorial/app-nativeresource-android.md#permissions)中配置要使用的权限,重新提交云端打包。
#### DISTRIBUTE配置 @app-distribute
<!-- MANIFESTJSON.app_distribute.description -->
<!-- MANIFESTJSON.app_distribute.table -->
##### App端图标配置 @distribute-icons
<!-- MANIFESTJSON.distribute_icons.description -->
<!-- MANIFESTJSON.distribute_icons.table -->
**注意**
- App端图片相关配置,建议在HBuilderX中 manifest.json 的可视化界面操作,不推荐手动在源码视图中修改
- manifest中只能配置一个icon。如需在应用发布后动态修改icon,可在插件市场搜索[动态图标插件](https://ext.dcloud.net.cn/search?q=%E5%8A%A8%E6%80%81%E5%9B%BE%E6%A0%87&orderBy=Relevance&cat1=8&cat2=81)
###### Android图标配置 @icons-android
<!-- MANIFESTJSON.icons_android.description -->
<!-- MANIFESTJSON.icons_android.table -->
###### iOS图标配置 @icons-ios
<!-- MANIFESTJSON.icons_ios.description -->
<!-- MANIFESTJSON.icons_ios.table -->
###### iPhone图标配置 @ios-iphone
<!-- MANIFESTJSON.ios_iphone.description -->
<!-- MANIFESTJSON.ios_iphone.table -->
###### iPad图标配置 @ios-ipad
<!-- MANIFESTJSON.ios_ipad.description -->
<!-- MANIFESTJSON.ios_ipad.table -->
##### ANDROID配置 @distribute-android
<!-- MANIFESTJSON.distribute_android.description -->
<!-- MANIFESTJSON.distribute_android.table -->
**注意**
- `abiFilters` 用于指定应用需要支持的CPU类型,字符串数组类型,字符串可取值"armeabi-v7a"、"arm64-v8a"、"x86"、"x86_64",默认值为["arm64-v8a"]。
- `minSdkVersion` 用于指定应用运行所需最低 API 级别的整数。如果系统的 API 级别低于该属性中指定的值,Android 系统将阻止用户安装应用。
- `targetSdkVersion` 一个用于指定应用的目标 API 级别的整数。如果未设置,其默认值与为 minSdkVersion 指定的值相等。该值用于通知系统,您已针对目标版本进行了测试,并且系统不应通过启用任何兼容性行为,以保持您的应用与目标版本的向前兼容性。
- `minSdkVersion``targetSdkVersion` 设置的值是 API 级别(API Level),完整API级别信息请参考[Android API级别说明](https://developer.android.com/guide/topics/manifest/uses-sdk-element?hl=zh-cn#ApiLevels)
##### IOS配置 @distribute-ios
<!-- MANIFESTJSON.distribute_ios.description -->
<!-- MANIFESTJSON.distribute_ios.table -->
## 示例
```json
{
"name" : "uni-app x",
"appid" : "__UNI__XXXXXXX",
"description" : "描述信息",
"versionName" : "1.0.0",
"versionCode" : "100",
"uni-app-x":{
"flex-direction": "column"
},
"vueVersion" : "3",
"app": {
"distribute": {
"syncDebug": true,
"android": {
"packagename": "Android包名",
"abiFilters": [
"armeabi-v7a","arm64-v8a"
],
"minSdkVersion": "21",
"targetSdkVersion": "32"
},
"ios": {
"appid": "iOS Bundle ID"
}
}
}
}
```
<!-- MANIFESTJSON.tutorial -->
\ No newline at end of file
# pages.json
`pages.json` 文件是 uni-app x 的页面管理配置文件,决定**应用的首页**、页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等。
**所有页面,均需在pages.json中注册,否则不会被打包到应用中。**
在HBuilderX中新建页面,默认会在pages.json中自动注册。在HBuilderX中删除页面文件,也会在状态栏提示从pages.json中移除注册。
除了管理页面,pages.json支持对页面进行特殊配置,比如应用首页的tabbar、每个页面的顶部导航栏设置。
但这些uni-app中设计的功能,主要是为了解决页面由webview渲染带来的性能问题,由原生提供一些配置来优化。
uni-app x的app平台,页面不再由webview渲染,其实不需要原生提供特殊配置来优化。但为了开发的便利和多端的统一,也支持了tabbar和导航栏设置。\
但不再支持uni-app的app-plus专用配置以及tabbar的midbutton。
如pages.json中配置的导航栏和tabbar功能无法满足你的需求,可以不在pages.json中配置,自己用view做导航栏和tabbar。\
hello uni-app x有相关示例,参考:
- 自定义导航栏:[插件地址](https://ext.dcloud.net.cn/plugin?id=14618)
- 自定义tabbar:[源码参考](https://gitcode.net/dcloud/hello-uni-app-x/-/tree/master/pages/template/custom-tab-bar)
插件市场也有其他封装好的插件,请自行搜索。
> 本文只包括 uni-app x 对 pages.json 支持情况。完整配置项详见 [pages.json 页面路由](https://uniapp.dcloud.net.cn/collocation/pages.html)
## 配置项列表
<!-- PAGESJSON.pages.description -->
<!-- PAGESJSON.pages.table -->
<!-- PAGESJSON.pages.compatibility -->
### globalStyle 配置项列表 @pages-globalstyle
globalStyle节点里是所有页面都生效的全局样式配置。它的配置与页面级style基本相同,但优先级低于页面级style配置。
<!-- PAGESJSON.pages_globalStyle.description -->
<!-- PAGESJSON.pages_globalStyle.table -->
<!-- PAGESJSON.pages_globalStyle.compatibility -->
### pages 配置项列表 @pagesoptionspage
pages节点里注册页面,数据格式是数组,数组每个项都是一个对象,通过path属性指定页面路径,通过style指定该页面的样式配置。
<!-- PAGESJSON.PagesOptionsPage.description -->
<!-- PAGESJSON.PagesOptionsPage.table -->
<!-- PAGESJSON.PagesOptionsPage.compatibility -->
**Tips:**
- **pages节点的第一项为应用入口页(即首页)**
- **应用中新增/减少页面**,都需要对 pages 数组进行修改
- 文件名**不需要写后缀**,框架会自动寻找路径下的页面资源
**示例**
假使开发目录为:
<pre v-pre="" data-lang="">
<code class="lang-" style="padding:0">
┌─pages
│ ├─index
│ │ └─index.uvue
│ └─login
│ └─login.uvue
├─static
├─main.uts
├─App.uvue
├─manifest.json
└─pages.json
</code>
</pre>
则需要在 pages.json 中填写
```javascript
{
"pages": [
{
"path": "pages/index/index",
"style": { ... }
}, {
"path": "pages/login/login",
"style": { ... }
}
]
}
```
#### style 配置项列表 @pagesoptionspage-style
用于设置每个页面的状态栏、导航条的颜色、文字等信息。
页面中配置项会覆盖 [globalStyle](#pages-globalstyle) 中相同的配置项
<!-- PAGESJSON.PagesOptionsPage_style.description -->
<!-- PAGESJSON.PagesOptionsPage_style.table -->
<!-- PAGESJSON.PagesOptionsPage_style.compatibility -->
**Tips**
- 状态栏
* 手机顶部状态栏的背景色、前景色(white/black)与navigationBarBackgroundColor和navigationBarTextStyle相同
* 当navigationStyle设为custom时,原生导航栏不显示。此时尤其需注意顶部状态栏的问题。
* 如需动态设置状态栏颜色,使用api [uni.setNavigationBarColor](./api/set-navigation-bar-color.md)
* 注意不同手机的状态栏高度并不相同,如需获取本机的状态栏高度,使用api [uni.getWindowInfo](./api/get-window-info.md)
- 下拉刷新
* pages.json中下拉刷新是页面级配置,方便使用但灵活度有限。
* 如需自定义下拉刷新,请使用[scroll-view](./component/scroll-view.md)[list-view](./component/list-view.md)的下拉刷新。
**style示例**
```javascript
{
"pages": [{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",//设置页面标题文字
"enablePullDownRefresh":true//开启下拉刷新
}
},
...
]
}
```
### tabBar 配置项列表 @pages-tabbar
tabbar节点用于配置应用的tabbar,仅支持配置一个。如需在更多页面配置tabbar,请使用view自行封装。
<!-- PAGESJSON.pages_tabBar.description -->
<!-- PAGESJSON.pages_tabBar.table -->
<!-- PAGESJSON.pages_tabBar.compatibility -->
#### PagesOptionsTabbarList 配置项列表 @pagesoptionstabbarlist
<!-- PAGESJSON.PagesOptionsTabbarList.description -->
<!-- PAGESJSON.PagesOptionsTabbarList.table -->
<!-- PAGESJSON.PagesOptionsTabbarList.compatibility -->
**tabbar示例**
```json
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/component/index",
"iconPath": "static/image/icon_component.png",
"selectedIconPath": "static/image/icon_component_HL.png",
"text": "组件"
}, {
"pagePath": "pages/API/index",
"iconPath": "static/image/icon_API.png",
"selectedIconPath": "static/image/icon_API_HL.png",
"text": "接口"
}]
}
```
### condition 配置项列表 @pages-condition
启动模式配置,仅开发期间生效,用于模拟直达页面的场景。教程[详见](https://uniapp.dcloud.net.cn/collocation/pages.html#condition)
<!-- PAGESJSON.pages_condition.description -->
<!-- PAGESJSON.pages_condition.table -->
<!-- PAGESJSON.pages_condition.compatibility -->
#### PagesConditionItem 配置项列表 @pagesconditionitem
<!-- PAGESJSON.PagesConditionItem.description -->
<!-- PAGESJSON.PagesConditionItem.table -->
<!-- PAGESJSON.PagesConditionItem.compatibility -->
### easycom 配置项列表 @pages-easycom
easycom是uni-app提供的一种简化组件使用的方式。一般情况下组件放置在符合规范的位置时即可自动引用。
但有时组件的路径或文件名无法满足easycom默认规范要求,可以在pages.json里进行规则的自定义。
自定义easycom的详细教程[详见](https://uniapp.dcloud.net.cn/collocation/pages.html#easycom)
<!-- PAGESJSON.pages_easycom.description -->
<!-- PAGESJSON.pages_easycom.table -->
<!-- PAGESJSON.pages_easycom.compatibility -->
<!-- PAGESJSON.tutorial -->
\ No newline at end of file
#### 什么是 uni-app x 编译器
`uni-app x`的编译器由uvue编译器、uts语言编译器共同组成,还调用了kotlin、swift编译器。
编译器把开发者书写的uvue和uts代码进行编译,配合运行时实现了跨平台。
uvue编译器是在Vite基础上进行扩展开发的。
它的大部分特性(如条件编译)和配置项(如环境变量)与`uni-app`的vue3编译器一致,[详见](https://uniapp.dcloud.net.cn/tutorial/compiler.html)
支持less、sass、scss等css预编译。
#### 编译缓存 @cache
`uni-app x`编译器引入了编译缓存机制,以优化开发体验。
在App端,`uni-app x`首先将uts和uvue编译为平台原生语言(如Kotlin),然后经过平台配套的编译器进行打包运行。
App原生语言的编译过程耗时较长,因此编译器引入了缓存机制来加快开发过程。
在编译时,开发者的uts和uvue代码的编译结果会被持久化为缓存,存在unpackage目录下。
当下次运行时,如果代码没有发生变动,编译器会优先使用缓存中的编译结果,从而加快编译速度。
缓存有可能失效,如果你修改代码后保存发现手机端没有更新,可以在HBuilderX运行窗口勾选`清理构建缓存`试下。
这个机制类似于传统强类型语言开发中的Build和clean。
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/clean-up-the-build-cache.jpg)#{.zooming width="400px"}
#### 注意 @tips
- `uni-app x`编译器会产生kt、class等临时文件。安全软件(如360、微软)会对其进行木马扫描,消耗电脑性能。建议将项目的unpackage目录设置为信任,以提升编译性能。
> 360设置方式
![](https://web-assets.dcloud.net.cn/hbuilderx-doc/360/360_1.png)#{.zooming width="400px"}
![](https://web-assets.dcloud.net.cn/hbuilderx-doc/360/360_2.png)#{.zooming width="400px"}
> 微软设置方式
![](https://web-assets.dcloud.net.cn/hbuilderx-doc/360/win_1.png)#{.zooming width="400px"}
![](https://web-assets.dcloud.net.cn/hbuilderx-doc/360/win_2.png)#{.zooming width="400px"}
* [概述](README.md)
* [条件编译](https://uniapp.dcloud.net.cn/tutorial/platform.html)
* [编译运行环境](https://uniapp.dcloud.net.cn/worktile/running-env.html)
* [编译静态资源](https://uniapp.dcloud.net.cn/tutorial/page-static-assets)
\ No newline at end of file
# uvue组件概述
uni-app x支持的组件包括:
- 内置基础组件
- 自定义vue组件
- uts组件插件
不支持的组件包括:
- 小程序wxml组件
支持[easycom](/component/README.md#easycom)
内置组件比较简单,扩展组件的2种方式详细介绍下
- 自定义vue组件
在components目录新建一个uvue/vue文件,按vue组件规范编写代码。
组件界面通过uvue构造,script使用uts编写。
返回的类型是组件实例[ComponentPublicInstance](../vue/api.md#ComponentPublicInstance)
- uts组件插件
`uts组件插件`的名称可能有点拗口,这是因为是相对于另一个分类`uts api插件`
它们同属于`uts插件`,是[uni_modules](../../plugin/uni_modules.md)。api插件指能力扩展,比如蓝牙api。而组件插件指界面元素扩展,比如video、map、lottie动画等。
uts组件插件,指把原生的、需要在界面上显示的、内嵌于页面中整体排版的组件,编写uts代码调用原生sdk,通过uni_modules插件的方式集成到uni-app项目中。比如
* lottie组件,使用uts调用原生的lottie sdk来开发组件,再引入页面中。[详见](https://ext.dcloud.net.cn/plugin?name=uni-animation-view)
* video组件,其实官方的video,也是用uts组件插件实现的。[详见](https://gitcode.net/dcloud/uni-component/-/tree/master/uni_modules/uni-video)
uts组件插件,主要用于原生sdk涉及界面时,将其封装为界面组件。当然uts组件也是全端支持的。上述lottie组件也支持web端。
在app端,它的内部界面是由原生sdk绘制的,而不是uvue代码绘制的。通过封装嵌入到uvue/nvue页面中。
一个uts插件都是可以同时兼容uni-app x和uni-app js引擎版的。目前js引擎版仅支持内嵌于nvue页面中。所以上述lottie组件也是可以在app-nvue页面中使用的。
uts组件的返回类型是dom元素[Element](../dom/element.md)
uts组件插件的开发教程,[详见](/plugin/uts-component.md)
**vue组件兼容性及注意事项:**
## props
- 仅支持[对象方式](https://cn.vuejs.org/guide/components/props.html#props-declaration)声明,不支持字符串数组方式声明。
- 仅支持直接在 `export default` 内部声明,不支持其他位置定义后,在 `export default` 中引用。
- 复杂数据类型需要通过 `PropType` 标记类型,[详见](https://cn.vuejs.org/guide/typescript/options-api.html#typing-component-props)
```ts
type Obj = { a: number }
export default {
props: {
num: {
type: Number,
required: true
},
str: {
type: String,
default: 'str',
validator(value: string): boolean {
return value.length > 0
}
},
obj: {
type: Object as PropType<Obj>,
default: (): Obj => ({ a: 1 } as Obj)
},
arr: {
type: Array as PropType<number[]>,
default: (): number[] => [1, 2, 3]
}
}
}
```
## 自定义组件 v-model 绑定复杂表达式 @v-model-complex-expression
自定义组件 `v-model` 绑定复杂表达式时,需要通过 `as` 指定类型。
```ts
<template>
<my-input v-model="obj.str as string" />
</template>
<script lang="uts">
type Obj = {
str : string
}
export default {
data() {
return {
obj: {
str: "str"
} as Obj
}
}
}
</script>
```
## 自定义事件
- [v-model](tutorial/vue3-components.html#v-model-modifiers) 暂不支持 `capitalize` 修饰符。
## 计算属性和侦听器
- [watch deep](https://uniapp.dcloud.net.cn/tutorial/vue3-basics.html#%E9%80%89%E9%A1%B9-deep) 不支持
- [监听对象中单个属性](https://uniapp.dcloud.net.cn/tutorial/vue3-basics.html#%E7%9B%91%E5%90%AC%E5%AF%B9%E8%B1%A1%E4%B8%AD%E5%8D%95%E4%B8%AA%E5%B1%9E%E6%80%A7) 不支持
## 作用域插槽的类型
作用域插槽需在组件中指定插槽数据类型
```ts
// components/Foo.uvue
<view>
<slot msg="test msg" />
</view>
import { SlotsType } from 'vue'
export default {
slots: Object as SlotsType<{
default: { msg: string }
}>
}
// page.uvue
<view>
<Foo>
<template v-slot="slotProps">
<text>{{ slotProps.msg }}</text>
</template>
</Foo>
</view>
```
## ref
`uni-app js 引擎版`中,非 `H5端` 只能用于获取自定义组件,不能用于获取内置组件实例(如:`view``text`)。\
`uni-app x` 中,内置组件会返回组件根节点的引用,自定义组件会返回组件实例。
**注意事项:**
- 如果多个节点或自定义组件绑定相同 `ref` 属性,将获取到最后一个节点或组件实例的引用。
-`v-for` 循环时,绑定 `ref` 属性会获取到节点或组件实例的集合。
-`uni-app x` 中,要访问 `$refs` 中的属性,需要使用索引方式。
::: preview
> uni-app js 引擎版
```ts
<template>
<view>
<text ref="text">text node</text>
<Foo ref="foo" />
</view>
</template>
<script lang="ts">
import type { ComponentPublicInstance } from 'vue'
export default {
onReady() {
const text = this.$refs.text as Element // 仅H5端支持
const foo = this.$refs.foo as ComponentPublicInstance
}
}
</script>
```
> uni-app x
```ts
<template>
<view>
<text ref="text">text node</text>
<Foo ref="foo" />
</view>
</template>
<script lang="uts">
import type { ComponentPublicInstance } from 'vue'
export default {
onReady() {
const text = this.$refs["text"] as Element
const foo = this.$refs["foo"] as ComponentPublicInstance
}
}
</script>
```
:::
## 监听页面生命周期
目前暂不支持在组件内监听页面生命周期,待后续支持组合式 API 后,可通过组合式 API 实现。
## vue 与 uvue 不同文件后缀的优先级 @priority
新建组件时,默认组件的后缀名为.uvue,但也支持.vue。
.vue里面写uvue的语法,可以正常被.uvue页面引用和编译。
.vue里写条件编译,可以制作同时满足uni-app和uni-app x的组件。
当你手动import或easycom手动配置规则,可以指定文件名后缀。比如`import PageHead from '@/components/page-head.uvue'`
但如果未明确指定组件后缀名的情况,且同一个组件目录下即存在.vue文件、又存在.uvue文件,
此时 `vue` 组件和 `uvue` 组件的优先级如下:
-`uni-app x` 中,优先使用 `uvue` 组件,如果不存在 `uvue` 组件,则使用 `vue` 组件。
-`uni-app` 中,只支持使用 `vue` 组件。
## 调用组件方法@methods
需要把组件分为 内置组件、easycom组件、非easycom组件,这3种组件有不同的方法调用方式。
### 内置组件的方法调用或设置属性
> 3.93+ 支持
使用 `this.$refs` 获取组件并as转换为组件对应的element类型,通过 `.`操作符 调用组件方法或设置属性。
**语法**
```(this.$refs['组件ref属性值'] as Uni[xxx]Element).foo();```
**内置组件的element类型规范**
Uni`组件名(驼峰)`Element
如:
`<button>`: UniButtonElement
`<picker-view>`: UniPickerViewElement
**示例代码**
```html
<template>
<view>
<slider ref="slider1"></slider>
</view>
</template>
<script>
export default {
data() {
return {
}
},
onReady() {
// value 为属性
(this.$refs["slider1"] as UniSliderElement).value = 10; //此处注意slider1必须存在,如不存在,把null as 成 UniSliderElement会引发崩溃
}
}
</script>
```
**bug&tips**
- 目前uts组件,即封装原生ui给uni-app或uni-app x的页面中使用,类型与内置组件的 Uni`组件名(驼峰)`Element 方式相同。目前没有代码提示。
### easycom组件调用方法或设置属性@method_easycom
> 3.97+ 支持 uni_modules 目录下的组件
easycom组件,用法和内置组件一样。也是使用 `this.$refs` 获取组件并转换为组件的类型,通过 `.`操作符 调用组件方法或设置属性。
**语法**
```(this.$refs['组件ref属性值'] as 驼峰ComponentPublicInstance).foo();```
**easycom组件的类型规范**
组件标签名首字母大写,驼峰+ComponentPublicInstance
如:
`<test/>` 类型为:TestComponentPublicInstance
`<uni-data-checkbox/>` 类型为:UniDataCheckboxComponentPublicInstance
**示例代码**
假使有一个component1组件,其有若干方法foo1等,如下。
```html
<template>
<view></view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
foo1() {
console.log("foo1");
},
foo2(date1 : number) {
console.log(date1);
},
foo3(date1 : number, date2 : number) {
},
foo4(callback : (() => void)) {
callback()
},
foo5(text1 : string) : any | null {
return text1
}
}
}
</script>
```
component1组件符合[easycom规范](https://uniapp.dcloud.net.cn/component/#easycom)
那么在页面中调用component1组件的方法如下:
```html
<template>
<view>
<component1 ref="component1"></component1>
</view>
</template>
<script>
export default {
data() {
return {
}
},
onReady() {
let c1 = (this.$refs["component1"] as Component1ComponentPublicInstance) //注意组件必须存在,注意类型首字母大写
c1.foo1();
c1.foo2(1);
}
}
</script>
```
### 其它自定义组件的方法调用使用callMethod@$callMethod
如果不是内置组件,也不是easycom组件,那么无法使用`.`操作符了。
此时需使用 `this.$refs` 获取组件实例,然后通过 `$callMethod` 调用组件的方法。也就是把组件的方法名、参数,当做callMethod的参数来传递。此时也就没有`.`操作符那样的代码提示和校验了。
callMethod可用于所有自定义组件,包括easycom组件也可以使用,只不过easycom组件有更简单的用法。
**语法**
```this.$refs['组件ref属性值'].$callMethod('方法名', ...args)```
**组件类型**
ComponentPublicInstance
页面示例代码 `page1.uvue`
```html
<template>
<view>
<component1 ref="component1"></component1>
</view>
</template>
<script>
// 导入 vue 组件实例类型
import { ComponentPublicInstance } from 'vue'
// 非easycom组件需import引用组件 component1.uvue
import component1 from './component1.uvue'
export default {
components: {
component1
},
data() {
return {
}
},
onReady() {
// 通过组件 ref 属性获取组件实例
const component1 = this.$refs['component1'] as ComponentPublicInstance;
// 通过 $callMethod 调用组件的 foo1 方法
component1.$callMethod('foo1');
// 通过 $callMethod 调用组件的 foo2 方法并传递 1个参数
component1.$callMethod('foo2', Date.now());
// 通过 $callMethod 调用组件的 foo3 方法并传递 2个参数
component1.$callMethod('foo3', Date.now(), Date.now());
// 通过 $callMethod 调用组件的 foo4 方法并传递 callback
component1.$callMethod('foo4', () => {
console.log('callback')
});
// 通过 $callMethod 调用组件的 foo5 方法并接收返回值
// 注意: 返回值可能为 null,当前例子一定不为空,所以加了 !
const result = component1.$callMethod('foo5', 'string1')! as string;
console.log(result); // string1
}
}
</script>
```
组件示例代码 `component1.uvue`
```html
<template>
<view></view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
foo1() {
},
foo2(date1 : number) {
},
foo3(date1 : number, date2 : number) {
},
foo4(callback : (() => void)) {
callback()
},
foo5(text1 : string) : any | null {
return text1
}
}
}
</script>
```
## 如何开发同时兼容 uni-app x 和 uni-app 的组件
目前有两种方案:
- 目录下同时提供uvue,vue文件,分别适配 uni-app x 和 uni-app
组件作者在 uvue 和 vue 文件中可以自由使用各自的特性,比如 vue 中可以任意使用 js 或 ts 来书写代码,
如果部分组件逻辑被抽离为单独的文件,需要分别命名为各自环境支持的文件类型,导入时不同平台支持的文件类型也不同,
比如 uvue 文件目前不支持引入js或ts,而 vue 文件不能引入 uts 文件
对于现有的 uni-app 组件,通过新建 uvue 文件来渐进式支持 uni-app x,可以避免对已有 uni-app 项目造成影响
- 仅提供一个vue文件,同时适配 uni-app x 和 uni-app
该方案,需要script节点配置lang="ts",这样才可以在 uni-app 项目中正常书写带有类型的代码,而在 uni-app x 项目中,则会忽略 lang="ts",当做 uts 代码编译。
当需要区分平台或项目类型时,可以使用对应的条件编译。
<!-- 比如,当需要在 css 中区分原生渲染和webview渲染时
可以通过 APP-UVUE(表示在 uni-app x 项目app端的Android和iOS原生渲染)、APP-NVUE(表示在 uni-app 项目app端的nvue页面原生渲染) 区分,
`#ifdef APP-UVUE || APP-NVUE` 可以表示原生渲染,使用 `ifndef` 则可以取反表示为webview渲染,如 `#ifndef APP-UVUE || APP-NVUE`
-->
比如通过 UNI-APP-X 来区分项目类型,更多条件编译见:[详情](https://uniapp.dcloud.net.cn/tutorial/platform.html)
\ No newline at end of file
* [概述](README.md)
* [公共属性和事件](common.md)
* 内置组件```{"collapsable": false}```
* [view](view.md)
* [scroll-view](scroll-view.md)
* [list-view](list-view.md)
* [sticky](sticky.md)
* [swiper](swiper.md)
* [navigator](navigator.md)
* [text](text.md)
* [rich-text](rich-text.md)
* [image](image.md)
* [input](input.md)
* [textarea](textarea.md)
* [button](button.md)
* [checkbox](checkbox-group.md)
* [radio](radio-group.md)
* [picker-view](picker-view.md)
* [progress](progress.md)
* [slider](slider.md)
* [switch](switch.md)
* [form](form.md)
* [video](video.md)
* [web-view](web-view.md)
* [animation-view](animation-view.md)
* [unicloud-db](unicloud-db.md)
* [未支持的组件及替代方案](unsupport.md)
\ No newline at end of file
## animation-view
<!-- UTSCOMJSON.animation-view.description -->
<!-- UTSCOMJSON.animation-view.attrubute -->
<!-- UTSCOMJSON.animation-view.event -->
<!-- UTSCOMJSON.animation-view.example -->
<!-- UTSCOMJSON.animation-view.compatibility -->
<!-- UTSCOMJSON.animation-view.children -->
<!-- UTSCOMJSON.animation-view.reference -->
## button
<!-- UTSCOMJSON.button.description -->
<!-- UTSCOMJSON.button.attrubute -->
<!-- UTSCOMJSON.button.event -->
<!-- UTSCOMJSON.button.example -->
<!-- UTSCOMJSON.button.compatibility -->
<!-- UTSCOMJSON.button.children -->
<!-- UTSCOMJSON.button.reference -->
## button样式修改@style
button在元素的text区域直接写文字,和text组件一样。可以这么理解,button是一个特殊的text组件,文字样式可以直接写在button组件的style或class上。
button组件属性中的size和type,属于预置样式,方便开发者使用。开发者也可以通过style和class来自定义样式。
button虽然可以内嵌text组件,但不建议通过text组件来修改button样式,因为会导致hove-class不生效。尤其是uvue中样式不继承。建议button组件text区域直接写文字,然后在button组件的style或class属性编写样式。
style和class的优先级,高于size和type属性。
```html
<template>
<button size="default" type="default"
style="color:#ffffff;backgroundColor:#1AAD19;borderColor:#1AAD19"
hover-class="is-hover">按钮</button>
</template>
<style>
.is-hover {
color: rgba(255, 255, 255, 0.6);
background-color: #179b16;
border-color: #179b16;
}
</style>
```
## button点击
button 组件的点击遵循 vue 标准的 @click事件。
button 组件没有 url 属性,如果要跳转页面,可以在@click中编写,也可以在button组件外面套一层 navigator 组件。举例,如需跳转到about页面,可按如下几种代码写法执行:
```html
<template>
<view>
<navigator url="/pages/about/about"><button>通过navigator组件跳转到about页面</button></navigator>
<button @click="goto('/pages/about/about')">通过方法跳转到about页面</button>
</view>
</template>
<script>
export default {
methods: {
goto(url:string) {
uni.navigateTo({
url:url
})
}
}
}
</script>
```
## tips
- button 的text区域文字,app-uvue下不支持 `\n` 方式换行,会直接显示 `\n` 字符。微信小程序下 `\n` 会变成一个空格
- button 的默认高度为46px,文字大小为18px,文字行高为46px。如果修改了默认高度,要注意手动调整文字行高
## checkbox-group
<!-- UTSCOMJSON.checkbox-group.description -->
<!-- UTSCOMJSON.checkbox-group.attrubute -->
<!-- UTSCOMJSON.checkbox-group.event -->
<!-- UTSCOMJSON.checkbox-group.example -->
<!-- UTSCOMJSON.checkbox-group.compatibility -->
<!-- UTSCOMJSON.checkbox-group.children -->
<!-- UTSCOMJSON.checkbox-group.reference -->
## checkbox
<!-- UTSCOMJSON.checkbox.description -->
<!-- UTSCOMJSON.checkbox.attrubute -->
<!-- UTSCOMJSON.checkbox.event -->
<!-- UTSCOMJSON.checkbox.example -->
<!-- UTSCOMJSON.checkbox.compatibility -->
<!-- UTSCOMJSON.checkbox.children -->
<!-- UTSCOMJSON.checkbox.reference -->
# 组件的公共属性和事件
每个组件都有属性和事件。有些属性和事件,是所有组件都支持的。
## 组件公共属性
- id
- ref
- style
- class
- data-
<!-- CUSTOMTYPEJSON.general-attribute.example -->
## 组件公共事件
- @touchstart
- @touchmove
- @touchend
- @touchcancel
- @tap
- @click //与tap等价
- @longpress
- @transitionend
在多点触摸的屏幕上,touch事件返回数组,包含了每个touch点对应的x、y坐标。
### transition 事件
- @transitionend
transition 效果结束时触发
#### 兼容性
安卓 3.93+ 版本开始支持
```vue
<template>
<image class="transition-transform" id="transition-transform" @transitionend="onEnd" src="/static/uni.png"></image>
</template>
<script>
export default {
data() {
return {}
},
onReady() {
var element = uni.getElementById('transition-transform')
element!.style.setProperty('transform', 'rotate(360deg)')
},
methods: {
onEnd() {
console.log("transition效果结束")
}
}
}
</script>
<style>
.transition-transform {
transition-duration: 2000;
transition-property: transform;
transform: rotate(0deg);
}
</style>
```
### 冒泡事件系统
DOM事件主要有三个阶段:捕获阶段、目标阶段和冒泡阶段。
以点击事件为例,当触发点击时,
1. 首先从根节点逐级向下分发,直到监听点击事件的节点为止(捕获阶段);
2. 然后事件到达当前节点并触发点击事件(目标阶段);
3. 接着继续向上逐级触发父节点的点击事件,直到根节点为止(冒泡阶段)。
注意,虽然有3个阶段,但第2个阶段(“目标阶段”:事件到达了元素)并没有单独处理:捕获和冒泡阶段的处理程序都会在该阶段触发。
我们一般使用默认的事件注册机制,将事件注册到冒泡阶段,相对来说,大多数处理情况都在冒泡阶段。
uvue 目前暂不支持事件的捕获阶段。
#### 阻止冒泡
在事件回调中,可以通过调用`event.stopPropagation`方法阻止事件冒泡。
```ts
handleClick (event : MouseEvent) {
// 阻止继续冒泡.
event.stopPropagation();
}
```
#### 阻止默认行为
在事件回调中,可以通过调用`event.preventDefault`方法阻止默认行为。`event.preventDefault`仅处理默认行为,事件冒泡不会被阻止。
```vue
<template>
<scroll-view style="flex: 1;">
<view style="width: 750rpx;height: 1750rpx;background-color: bisque;">
滑动框中区域修改进度并阻止滚动,滑动其余空白区域触发滚动
<view style="width: 750rpx;height: 40rpx; margin-top: 100rpx;border:5rpx;" @touchmove="slider">
<view ref="view1" style="background-color: chocolate;width: 0rpx;height: 30rpx;"></view>
</view>
</view>
</scroll-view>
</template>
<script>
export default {
data() {
return {
$view1Element: null as UniElement | null
}
},
onReady() {
this.$view1Element = this.$refs['view1'] as UniElement
},
methods: {
slider(e : TouchEvent) {
e.preventDefault() // 阻止外层scroll-view滚动行为
this.$view1Element!.style?.setProperty('width', e.touches[0].screenX);
}
}
}
</script>
```
## Event
<!-- CUSTOMTYPEJSON.Event.description -->
<!-- CUSTOMTYPEJSON.Event.extends -->
<!-- CUSTOMTYPEJSON.Event.param -->
### Event 方法 @event-methods
<!-- CUSTOMTYPEJSON.Event.methods.stopPropagation.name -->
<!-- CUSTOMTYPEJSON.Event.methods.stopPropagation.description -->
<!-- CUSTOMTYPEJSON.Event.methods.stopPropagation.param -->
<!-- CUSTOMTYPEJSON.Event.methods.stopPropagation.returnValue -->
<!-- CUSTOMTYPEJSON.Event.methods.stopPropagation.compatibility -->
<!-- CUSTOMTYPEJSON.Event.methods.stopPropagation.tutorial -->
<!-- CUSTOMTYPEJSON.Event.methods.preventDefault.name -->
<!-- CUSTOMTYPEJSON.Event.methods.preventDefault.description -->
<!-- CUSTOMTYPEJSON.Event.methods.preventDefault.param -->
<!-- CUSTOMTYPEJSON.Event.methods.preventDefault.returnValue -->
<!-- CUSTOMTYPEJSON.Event.methods.preventDefault.compatibility -->
<!-- CUSTOMTYPEJSON.Event.methods.preventDefault.tutorial -->
## CustomEvent
<!-- CUSTOMTYPEJSON.CustomEvent.description -->
<!-- CUSTOMTYPEJSON.CustomEvent.extends -->
<!-- CUSTOMTYPEJSON.CustomEvent.param -->
### CustomEvent 方法 @customevent-methods
<!-- CUSTOMTYPEJSON.CustomEvent.methods.stopPropagation.name -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.stopPropagation.description -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.stopPropagation.param -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.stopPropagation.returnValue -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.stopPropagation.compatibility -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.stopPropagation.tutorial -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.preventDefault.name -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.preventDefault.description -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.preventDefault.param -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.preventDefault.returnValue -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.preventDefault.compatibility -->
<!-- CUSTOMTYPEJSON.CustomEvent.methods.preventDefault.tutorial -->
## CustomEventOptions
<!-- CUSTOMTYPEJSON.CustomEventOptions.description -->
<!-- CUSTOMTYPEJSON.CustomEventOptions.extends -->
<!-- CUSTOMTYPEJSON.CustomEventOptions.param -->
## MouseEvent
<!-- CUSTOMTYPEJSON.MouseEvent.description -->
<!-- CUSTOMTYPEJSON.MouseEvent.extends -->
<!-- CUSTOMTYPEJSON.MouseEvent.param -->
### MouseEvent 方法 @mouseevent-methods
<!-- CUSTOMTYPEJSON.MouseEvent.methods.stopPropagation.name -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.stopPropagation.description -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.stopPropagation.param -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.stopPropagation.returnValue -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.stopPropagation.compatibility -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.stopPropagation.tutorial -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.preventDefault.name -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.preventDefault.description -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.preventDefault.param -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.preventDefault.returnValue -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.preventDefault.compatibility -->
<!-- CUSTOMTYPEJSON.MouseEvent.methods.preventDefault.tutorial -->
## TouchEvent
<!-- CUSTOMTYPEJSON.TouchEvent.description -->
<!-- CUSTOMTYPEJSON.TouchEvent.extends -->
<!-- CUSTOMTYPEJSON.TouchEvent.param -->
### TouchEvent 方法 @touchevent-methods
<!-- CUSTOMTYPEJSON.TouchEvent.methods.stopPropagation.name -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.stopPropagation.description -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.stopPropagation.param -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.stopPropagation.returnValue -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.stopPropagation.compatibility -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.stopPropagation.tutorial -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.preventDefault.name -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.preventDefault.description -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.preventDefault.param -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.preventDefault.returnValue -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.preventDefault.compatibility -->
<!-- CUSTOMTYPEJSON.TouchEvent.methods.preventDefault.tutorial -->
## Touch
<!-- CUSTOMTYPEJSON.Touch.description -->
<!-- CUSTOMTYPEJSON.Touch.extends -->
<!-- CUSTOMTYPEJSON.Touch.param -->
<!-- CUSTOMTYPEJSON.general-event.example -->
\ No newline at end of file
## form
<!-- UTSCOMJSON.form.description -->
<!-- UTSCOMJSON.form.attrubute -->
<!-- UTSCOMJSON.form.event -->
<!-- UTSCOMJSON.form.example -->
<!-- UTSCOMJSON.form.compatibility -->
### submit策略差异
form 组件的表单提交,微信小程序的实现策略,与浏览器W3C的策略略有差异。目前uni-app在app和web上的实现参考了微信小程序。具体是:
- uni-app表单提交的数据是一个对象`{"name": "value"}`。而浏览器标准form是数组,每项为 pair,pair[0] 对应name,pair[1] 对应value 。
- 多个表单子项如果 name 相同,仅保留最后一个表单子项。而浏览器标准form整体是数组,不存在覆盖的情况。
- 设置 disabled 属性的表单子项,仍然会提交。而浏览器标准form提交时会忽略disabled的表单子项。
注意uni-app编译到web平台,也是按uni-app的策略,而不是浏览器的策略。uni-app 的 web平台使用 uni-app 自己的 form 组件,而不是浏览器的 form 标签。
### reset策略差异
reset在浏览器W3C的策略是还原、重置。
在uni-app中,不同平台的策略不同,有的是`还原`,有的是`清空`
各平台策略如下:
|uni-app-x App |uni-app App|Web |微信小程序 |支付宝小程序 |百度小程序 |抖音小程序 |
|:-: |:-: |:-: |:-: |:-: |:-: |:-: |
|还原(3.97+) |清空 |清空 |清空 |还原 |清空 |清空 |
1. 还原初始值
```html
<!-- reset 后为 name -->
<input name="input1" value="name" />
<!-- reset 后为 true -->
<switch name="switch1" :checked="true" />
<!-- reset 后为 50 -->
<slider name="slider1" :value="50" :min="10" :max="110" />
<!-- reset 后为 "写字" 被 checked -->
<checkbox-group name="loves">
<view>
<checkbox value="0" /><text>读书</text>
</view>
<view>
<checkbox value="1" :checked="true" /><text>写字</text>
</view>
</checkbox-group>
```
2. 清空已有值(含初始值和改变后的值)
```html
<!-- reset 后为 "" -->
<input name="input1" value="name" />
<!-- reset 后为 false -->
<switch name="switch1" :checked="true" />
<!-- reset 后为 最小值10 -->
<slider name="slider1" :value="50" :min="10" :max="110" />
<!-- reset 后为 无任何 checked -->
<checkbox-group name="loves">
<view>
<checkbox value="0" /><text>读书</text>
</view>
<view>
<checkbox value="1" :checked="true" /><text>写字</text>
</view>
</checkbox-group>
```
<!-- UTSCOMJSON.form.children -->
<!-- UTSCOMJSON.form.reference -->
## Bug & Tips
- 安卓 uni-app-x 暂不支持自定义组件内的表单组件
## image
<!-- UTSCOMJSON.image.description -->
<!-- UTSCOMJSON.image.attrubute -->
<!-- UTSCOMJSON.image.event -->
### 图片格式
- [x] bmp
- [x] gif
- [x] ico
- [x] jpg
- [x] png
- [x] webp
- [x] heic(Android10+支持)
如需其他图片格式,可自行开发uts组件插件或搜索插件市场,如
- [svg插件](https://ext.dcloud.net.cn/search?q=svg&orderBy=Relevance&cat1=8&cat2=82)
- [apng插件](https://ext.dcloud.net.cn/search?q=apng&orderBy=Relevance&cat1=8&cat2=82)
### src路径支持说明
- 本地路径/static方式
由于uni-app编译时,只把/static目录下的静态资源copy到app中,所以src均需指向/static目录下。
其他目录的图片由于不会被打包进去,所以无法访问。
本地路径的大小写,在真机运行时由于运行在sd卡上所以不敏感,但在打包后整合到apk中由于Android系统的要求是大小写敏感的。
- 本地绝对路径file:///方式
形如`file:///storage/emulated/0/Android/data/io.dcloud.uniappx/apps/__UNI__4517034/www/static/test-image/logo.png`
访问本应用内的资源时无需使用本方式,推荐使用/static方式。上述地址受包名、appid影响。
file:///方式一般用于download等公共目录。使用前需确保拥有相关权限。
- 支持网络路径
支持http、https。
image组件内部使用facebook的[fresco](https://github.com/facebook/fresco)库(2.5.0),自带缓存策略,也会自动清理缓存。
<!-- UTSCOMJSON.image.example -->
<!-- UTSCOMJSON.image.compatibility -->
<!-- UTSCOMJSON.image.children -->
<!-- UTSCOMJSON.image.reference -->
### tips
- 在error事件里监听报错,并重新设置image组件的src,可实现自定义错误图。[详见示例代码](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/master/pages/component/image/image-path.uvue)
- 图片文件需在static目录(项目下或uni_modules下都支持static目录)下,或者import导入文件,否则文件不会被copy到最终的包中,导致无法访问。
\ No newline at end of file
## input
<!-- UTSCOMJSON.input.description -->
<!-- UTSCOMJSON.input.attrubute -->
<!-- UTSCOMJSON.input.event -->
<!-- UTSCOMJSON.input.example -->
<!-- UTSCOMJSON.input.compatibility -->
<!-- UTSCOMJSON.input.children -->
<!-- UTSCOMJSON.input.reference -->
## list-view
<!-- UTSCOMJSON.list-view.description -->
在App中,基于recycle-view的list,才能实现长列表的资源自动回收,以保障列表加载很多项目时,屏幕外的资源被有效回收。list-view就是基于recycle-view的list组件。
每个list由1个父组件list-view及若干子组件list-item构成。仅有有限子组件可识别,[见下](#children-tags)
list-view和scroll-view都是滚动组件,list适用于长列表场景,其他场景适用于scroll-view。
list-view支持通过子组件sticky-header处理吸顶的场景。
<!-- UTSCOMJSON.list-view.attrubute -->
<!-- UTSCOMJSON.list-view.event -->
<!-- UTSCOMJSON.list-view.example -->
### 自定义下拉刷新样式
list-view组件有默认的下拉刷新样式,如果想自定义,则需使用自定义下拉刷新。
1. 设置`refresher-default-style`属性为 none 不使用默认样式
2. 设置 list-item 定义自定义下拉刷新元素并声明为 `slot="refresher"`,需要设置刷新元素宽高信息否则可能无法正常显示!
```html
<template>
<list-view refresher-default-style="none" :refresher-enabled="true" :refresher-triggered="refresherTriggered"
@refresherpulling="onRefresherpulling" @refresherrefresh="onRefresherrefresh"
@refresherrestore="onRefresherrestore" style="flex:1" >
<list-item v-for="i in 10" class="content-item">
<text class="text">item-{{i}}</text>
</list-item>
<!-- 自定义下拉刷新元素 -->
<list-item slot="refresher" class="refresh-box">
<text class="tip-text">{{text[state]}}</text>
</list-item>
</list-view>
</template>
```
3. 通过组件提供的refresherpulling、refresherrefresh、refresherrestore、refresherabort下拉刷新事件调整自定义下拉刷新元素!实现预期效果
**注意:**
+ 3.93版本开始支持
+ 目前自定义下拉刷新元素不支持放在list-view的首个子元素位置上。可能无法正常显示
<!-- UTSCOMJSON.list-view.compatibility -->
<!-- UTSCOMJSON.list-view.children -->
<!-- UTSCOMJSON.list-view.reference -->
## list-item
<!-- UTSCOMJSON.list-item.description -->
<!-- UTSCOMJSON.list-item.attrubute -->
### list-item复用机制
+ type属性定义list-item组件类型。不赋值type属性默认值为0,每一个type类型都会有对应的list-item组件缓存池。
+ list-view组件加载list-item组件时,会优先查询对应type缓存池是否存在可复用的list-item组件。有则复用没有则创建新的list-item组件。
+ list-item组件被滑动出屏幕则会优先添加到对应类型的list-item缓存池,每个类型缓存最大5个(不同平台缓存最大值不固定),如果缓存池已满则进行组件销毁!
+ 部分list-item组件存在子元素个数差异或排版差异时。请尽可能的配置不同的type,这样可以规避获取相同type类型的list-item组件后。
* 很常见的一个错误是在长列表上方的list-item里放置banner图,却没有为这个不可复用的list-item设置单独的type,这会导致图片在复用失败后无法渲染。
* 由于子元素差异导致list-item无法正常复用问题。具体可参考示例:
```html
<template>
<view class="content">
<list-view ref="listView" class="list" :scroll-y="true">
<list-item v-for="(item,index) in list" :key="index" class="content-item1" type=1>
<text class="text">title-{{item}}</text>
<text class="text">content-{{item}}</text>
</list-item>
<list-item v-for="(item,index) in list" :key="index" class="content-item2" type=2>
<image class="image" src ="/static/test-image/logo.png"></image>
</list-item>
<list-item type=3>
<text class="loading">{{text}}</text>
</list-item>
</list-view>
</view>
</template>
```
示例中有三种类型的list-item组件。如果都不赋值type,list-item组件滑动出屏幕后都归类到type=0的缓存池。当触发list-item组件重新加载时,获取type=0的缓存池的组件,获取到的list-item组件可能是两个text子组件也可能是一个image子组件或一个text子组件,底层复用判断时则认为该情况异常不复用,重新创建新的list-item组件!复用失败未能优化性能。正确的方式则是不同的类型设置不同的type。加载时则会获取对应type类型缓存池中的list-item组件实现复用。
**注意:**
1. 避免对list-item组件的子元素设置event事件,复用后list-item组件部分子元素可能无法正常响应event,有相关业务需要对子元素设置event事件,可对list-item组件设置独立的type实现不复用。
<!-- UTSCOMJSON.list-item.event -->
<!-- UTSCOMJSON.list-item.example -->
<!-- UTSCOMJSON.list-item.compatibility -->
<!-- UTSCOMJSON.list-item.children -->
<!-- UTSCOMJSON.list-item.reference -->
## 示例代码
- 联网联表:[https://gitcode.net/dcloud/hello-uni-app-x/-/blob/master/pages/template/list-news/list-news.uvue](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/master/pages/template/list-news/list-news.uvue)
- 可左右滑动的多个列表:[https://gitcode.net/dcloud/hello-uni-app-x/-/tree/master/pages/template/long-list](https://gitcode.net/dcloud/hello-uni-app-x/-/tree/master/pages/template/long-list)
### Bug & Tips@tips
- 暂不支持reverse,目前还不能开发im那样的倒序列表
- 多列瀑布流是另外的组件,后续会提供
- list-view组件的overflow属性不支持配置visible
## navigator
<!-- UTSCOMJSON.navigator.description -->
<!-- UTSCOMJSON.navigator.attrubute -->
<!-- UTSCOMJSON.navigator.event -->
<!-- UTSCOMJSON.navigator.example -->
<!-- UTSCOMJSON.navigator.compatibility -->
<!-- UTSCOMJSON.navigator.children -->
<!-- UTSCOMJSON.navigator.reference -->
## picker-view
<!-- UTSCOMJSON.picker-view.description -->
<!-- UTSCOMJSON.picker-view.attrubute -->
<!-- UTSCOMJSON.picker-view.event -->
<!-- UTSCOMJSON.picker-view.example -->
<!-- UTSCOMJSON.picker-view.compatibility -->
<!-- UTSCOMJSON.picker-view.children -->
<!-- UTSCOMJSON.picker-view.reference -->
## picker-view-column
<!-- UTSCOMJSON.picker-view-column.description -->
<!-- UTSCOMJSON.picker-view-column.attrubute -->
<!-- UTSCOMJSON.picker-view-column.event -->
<!-- UTSCOMJSON.picker-view-column.example -->
<!-- UTSCOMJSON.picker-view-column.compatibility -->
<!-- UTSCOMJSON.picker-view-column.children -->
<!-- UTSCOMJSON.picker-view-column.reference -->
## tips
- picker里如放置较长内容,应该使用list-view而不是scroll-view。
## progress
<!-- UTSCOMJSON.progress.description -->
<!-- UTSCOMJSON.progress.attrubute -->
<!-- UTSCOMJSON.progress.event -->
<!-- UTSCOMJSON.progress.example -->
<!-- UTSCOMJSON.progress.compatibility -->
<!-- UTSCOMJSON.progress.children -->
<!-- UTSCOMJSON.progress.reference -->
## radio-group
<!-- UTSCOMJSON.radio-group.description -->
<!-- UTSCOMJSON.radio-group.attrubute -->
<!-- UTSCOMJSON.radio-group.event -->
<!-- UTSCOMJSON.radio-group.example -->
<!-- UTSCOMJSON.radio-group.compatibility -->
<!-- UTSCOMJSON.radio-group.children -->
<!-- UTSCOMJSON.radio-group.reference -->
## radio
<!-- UTSCOMJSON.radio.description -->
<!-- UTSCOMJSON.radio.attrubute -->
<!-- UTSCOMJSON.radio.event -->
<!-- UTSCOMJSON.radio.example -->
<!-- UTSCOMJSON.radio.compatibility -->
<!-- UTSCOMJSON.radio.children -->
<!-- UTSCOMJSON.radio.reference -->
## rich-text
<!-- UTSCOMJSON.rich-text.description -->
### 支持的HTML标签和属性
|HTML |属性 |样式 |
|-------|-------|-------|
|br | | |
|p | |text-align color background-color text-decoration|
|ul | | |
|li | |text-align color background-color text-decoration|
|span | |color background-color text-decoration|
|strong | | |
|i | | |
|big | | |
|small | | |
|a |href | |
|u | | |
|del | | |
|h1-h6 | | |
|img |src | |
> text-decoration仅支持line-through
<!-- UTSCOMJSON.rich-text.attrubute -->
<!-- UTSCOMJSON.rich-text.event -->
<!-- UTSCOMJSON.rich-text.example -->
<!-- UTSCOMJSON.rich-text.compatibility -->
<!-- UTSCOMJSON.rich-text.children -->
<!-- UTSCOMJSON.rich-text.reference -->
## Bug & Tips@tips
- HTML String支持常用但不是全部web样式。
- HTML String类型的`<img/>`不支持自定义宽高,默认以rich-text组件宽度为基准等比缩放;节点列表类型的`<img>/`支持自定义宽高。
## scroll-view
<!-- UTSCOMJSON.scroll-view.description -->
<!-- UTSCOMJSON.scroll-view.attrubute -->
<!-- UTSCOMJSON.scroll-view.event -->
<!-- UTSCOMJSON.scroll-view.example -->
### 自定义下拉刷新样式
1. 设置`refresher-default-style`属性为 none 不使用默认样式
2. 自定义下拉刷新元素必须要声明为 slot="refresher",需要设置刷新元素宽高信息否则可能无法正常显示!
3. 通过组件提供的refresherpulling、refresherrefresh、refresherrestore、refresherabort下拉刷新事件调整自定义下拉刷新元素!实现预期效果
**注意:** 目前自定义下拉刷新元素不支持放在scroll-view的首个子元素位置上。可能无法正常显示
```vue
<scroll-view refresher-default-style="none" :refresher-enabled="true" :refresher-triggered="refresherTriggered"
@refresherpulling="onRefresherpulling" @refresherrefresh="onRefresherrefresh"
@refresherrestore="onRefresherrestore" style="flex:1" >
<view v-for="i in 20" class="content-item">
<text class="text">item-{{i}}</text>
</view>
<!-- 自定义下拉刷新元素 -->
<view slot="refresher" class="refresh-box">
<text class="tip-text">{{text[state]}}</text>
</view>
</scroll-view>
```
**具体代码请参考:**[自定义下拉刷新样式示例](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/alpha/pages/component/scroll-view/scroll-view-custom-refresher-props.uvue)
### nested-scroll嵌套滚动协商@nested
嵌套滚动是原生才有的概念,web没有。
它是指父子2个滚动容器嵌套,在滚动时可以互相协商,控制父容器怎么滚、子容器怎么滚。
1. 通过在子滚动容器设置`custom-nested-scroll = true`,开启与父组件实现嵌套滚动协商。仅list-view、scroll-view组件支持与父组件嵌套滚动协商。
下面的示例代码,在一个scroll-view中嵌套了一个list-view。在list-view上设置了custom-nested-scroll="true"。
```html
<scroll-view style="height: 100%;" scroll-y="true" rebound ="false" nested-scroll-child="listview" @startnestedscroll="onStartNestedScroll" @nestedprescroll="onNestedPreScroll"
@stopnestedscroll="onStopNestedScroll">
...
<view style="height: 100px;">停靠视图</view>
<list-view id="listview" class="child-scroll" scroll-y="true" custom-nested-scroll="true">
...
</list-view>
</scroll-view>
```
2. 子组件准备滚动时会触发父组件的`startnestedscroll`事件。父组件响应`startnestedscroll`事件return ture则表示与子组件建立嵌套滚动协商。
```ts
onStartNestedScroll(event: StartNestedScrollEvent): Boolean {
//开启与子组件建立嵌套滚动协商
return true
}
```
3. 当建立嵌套滚动协商后,子组件滚动时父组件会持续收到`nestedprescroll`事件,这个事件的含义是嵌套滚动即将发生。
事件中会返回NestedPreScrollEvent子组件将要滚动的数据。
4. 父组件执行NestedPreScrollEvent.consumed(x,y)函数,告知子组件本次`nestedprescroll`事件deltaX、deltaY各消耗多少,即父组件要消费掉多少滚动距离。
子组件将执行差值后的deltaX、deltaY滚动距离,也就是剩余的滚动余量留给子组件。
```ts
onNestedPreScroll(event: NestedPreScrollEvent) {
var deltaY = event.deltaY
var deltaX = event.deltaX
...
if() {
//告知子组件deltaX、deltaY各消耗多少
event.consumed(x, y)
}
}
```
5. 父组件配置`nested-scroll-child`后,父组件惯性滚动时会让`nested-scroll-child`配置的子元素进行滚动。从而触发`nestedprescroll`协商处理滚动事件
6. 滚动行为停止后会触发`stopnestedscroll`事件
**注意:**
+ 仅Android平台支持嵌套滚动协商
+ 嵌套滚动协商仅支持竖向滚动,横向滚动不支持
+ nested-scroll-child设置的元素必须配置custom-nested-scroll = true,否则配置无效。
**具体代码请参考:**[nested-scroll嵌套滚动示例](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/alpha/pages/template/long-list/long-list.uvue)
<!-- UTSCOMJSON.scroll-view.compatibility -->
<!-- UTSCOMJSON.scroll-view.children -->
<!-- UTSCOMJSON.scroll-view.reference -->
### Bug & Tips@tips
- scroll-view组件的overflow属性不支持配置visible
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册