Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
unidocs-zh
提交
bb6a05c0
unidocs-zh
项目概览
DCloud
/
unidocs-zh
通知
3559
Star
107
Fork
909
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
118
列表
看板
标记
里程碑
合并请求
104
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
unidocs-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
118
Issue
118
列表
看板
标记
里程碑
合并请求
104
合并请求
104
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
bb6a05c0
编写于
9月 10, 2023
作者:
W
wanganxp
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
x
上级
7e17f1ed
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
263 addition
and
156 deletion
+263
-156
docs/tutorial/platform.md
docs/tutorial/platform.md
+31
-16
docs/uni-app-x/_sidebar.md
docs/uni-app-x/_sidebar.md
+1
-0
docs/uni-app-x/component/README.md
docs/uni-app-x/component/README.md
+29
-0
docs/uni-app-x/component/readme.md
docs/uni-app-x/component/readme.md
+29
-0
docs/uni-app-x/project.md
docs/uni-app-x/project.md
+54
-0
docs/uni-app-x/readme.md
docs/uni-app-x/readme.md
+4
-26
docs/uni-app-x/static/newproject.png
docs/uni-app-x/static/newproject.png
+0
-0
docs/uni-app-x/static/playground.jpg
docs/uni-app-x/static/playground.jpg
+0
-0
docs/uni-app-x/tutorial/request.md
docs/uni-app-x/tutorial/request.md
+31
-13
docs/uts/data-type.md
docs/uts/data-type.md
+84
-101
未找到文件。
docs/tutorial/platform.md
浏览文件 @
bb6a05c0
...
@@ -196,20 +196,20 @@ json的条件编译,如不同平台的key名称相同,cli项目下开发者
...
@@ -196,20 +196,20 @@ json的条件编译,如不同平台的key名称相同,cli项目下开发者
在不同平台,引用的静态资源可能也存在差异,通过 static 的条件编译可以解决此问题,static 目录下新建不同平台的专有目录,目录名称均为小写,
在不同平台,引用的静态资源可能也存在差异,通过 static 的条件编译可以解决此问题,static 目录下新建不同平台的专有目录,目录名称均为小写,
|目录名称
|说明|版本支持
|
|目录名称
|说明 |版本支持
|
|:-:
|:-:|:-:
|
|:-:
|:-: |:-:
|
|app
或app-plus|App|
|
|app
-plus |app(推荐使用
`app`
) |
|
|
h5|H5(推荐使用
`web`
)
|
|
app |app |uni-app 3.9+
|
|
web|Web(同
`H5`
,HBuilderX3.9.0+)|
|
|
h5 |H5(推荐使用
`web`
) |
|
|web
|H5|HBuilderX 3.9.0+
|
|web
|web |uni-app 3.9+
|
|mp-weixin
|微信小程序|
|
|mp-weixin
|微信小程序 |
|
|mp-alipay
|支付宝小程序|
|
|mp-alipay
|支付宝小程序 |
|
|mp-baidu
|百度小程序|
|
|mp-baidu
|百度小程序 |
|
|mp-qq
|QQ小程序|
|
|mp-qq
|QQ小程序 |
|
|mp-toutiao
|抖音小程序|
|
|mp-toutiao
|抖音小程序 |
|
|mp-lark
|飞书小程序|
|
|mp-lark
|飞书小程序 |
|
|mp-kuaishou|快手小程序
|
|
|mp-kuaishou|快手小程序
|
|
|mp-jd
|京东小程序|
|
|mp-jd
|京东小程序 |
|
专有目录下的静态资源只有在特定平台才会编译进去。
专有目录下的静态资源只有在特定平台才会编译进去。
...
@@ -230,7 +230,7 @@ json的条件编译,如不同平台的key名称相同,cli项目下开发者
...
@@ -230,7 +230,7 @@ json的条件编译,如不同平台的key名称相同,cli项目下开发者
**注意**
**注意**
-
自HBuilderX3.9
.0
+起,App平台static目录同时支持app、app-plus目录,Web平台static目录同时支持web、h5目录
-
自HBuilderX3.9+起,App平台static目录同时支持app、app-plus目录,Web平台static目录同时支持web、h5目录
### 整体目录条件编译
### 整体目录条件编译
...
@@ -280,12 +280,27 @@ json的条件编译,如不同平台的key名称相同,cli项目下开发者
...
@@ -280,12 +280,27 @@ json的条件编译,如不同平台的key名称相同,cli项目下开发者
:::
:::
### 编译器版本的条件编译@uniVersion
### 版本的条件编译@uniVersion
> HBuilderX 3.9+
插件作者的插件,需要适配各种插件使用者,使用者的uni-app版本,可能有很多。
有些问题可以在运行期判断适配,有些则需要在编译器处理,尤其是不处理可能会导致低版本编译失败的情况。
为此,uni-app的条件编译新增了
`uniVersion`
。在uni-app和uni-app x中均可使用。
<pre
v-pre=
""
data-lang=
"javascript"
><code
class=
"lang-javascript code"
><span
class=
"token comment"
>
//
<span
style=
"color:#859900;"
>
#ifdef
</span><b
style=
"color:#268BD2"
>
uniVersion > 3.9
</b></span>
<pre
v-pre=
""
data-lang=
"javascript"
><code
class=
"lang-javascript code"
><span
class=
"token comment"
>
//
<span
style=
"color:#859900;"
>
#ifdef
</span><b
style=
"color:#268BD2"
>
uniVersion > 3.9
</b></span>
编译器版本大于3.9时生效
编译器版本大于3.9时生效
<span
class=
"token comment"
>
//
<span
style=
"color:#859900;"
>
#endif
</span></span></code></pre>
<span
class=
"token comment"
>
//
<span
style=
"color:#859900;"
>
#endif
</span></span></code></pre>
注意,从HBuilderX 3.9起,版本号将由三段式字符串改为小数。
即HBuilderX 3.9.1,将改为 3.91。
这样条件编译判断时,仅需输入一个数字即可。
注意低于3.9版本的HBuilderX的条件编译不识别
`uniVersion`
。
### HBuilderX 支持
### HBuilderX 支持
HBuilderX 为
``uni-app``
的条件编译提供了丰富的支持:
HBuilderX 为
``uni-app``
的条件编译提供了丰富的支持:
...
...
docs/uni-app-x/_sidebar.md
浏览文件 @
bb6a05c0
*
[
概述
](
README.md
)
*
[
概述
](
README.md
)
*
[
项目
](
project.md
)
*
教程
*
教程
*
[
与js开发的差别
](
tutorial/codegap.md
)
*
[
与js开发的差别
](
tutorial/codegap.md
)
*
[
request联网教程
](
tutorial/request.md
)
*
[
request联网教程
](
tutorial/request.md
)
...
...
docs/uni-app-x/component/README.md
浏览文件 @
bb6a05c0
...
@@ -76,3 +76,32 @@ export default {
...
@@ -76,3 +76,32 @@ export default {
此时
`vue`
组件和
`uvue`
组件的优先级如下:
此时
`vue`
组件和
`uvue`
组件的优先级如下:
-
在
`uni-app x`
中,优先使用
`uvue`
组件,如果不存在
`uvue`
组件,则使用
`vue`
组件。
-
在
`uni-app x`
中,优先使用
`uvue`
组件,如果不存在
`uvue`
组件,则使用
`vue`
组件。
-
在
`uni-app`
中,只支持使用
`vue`
组件。
-
在
`uni-app`
中,只支持使用
`vue`
组件。
## 如何开发同时兼容 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
docs/uni-app-x/component/readme.md
浏览文件 @
bb6a05c0
...
@@ -76,3 +76,32 @@ export default {
...
@@ -76,3 +76,32 @@ export default {
此时
`vue`
组件和
`uvue`
组件的优先级如下:
此时
`vue`
组件和
`uvue`
组件的优先级如下:
-
在
`uni-app x`
中,优先使用
`uvue`
组件,如果不存在
`uvue`
组件,则使用
`vue`
组件。
-
在
`uni-app x`
中,优先使用
`uvue`
组件,如果不存在
`uvue`
组件,则使用
`vue`
组件。
-
在
`uni-app`
中,只支持使用
`vue`
组件。
-
在
`uni-app`
中,只支持使用
`vue`
组件。
## 如何开发同时兼容 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
docs/uni-app-x/project.md
0 → 100644
浏览文件 @
bb6a05c0
# uni-app x项目
## 新建
在HBuilder3.9起,新建uni-app项目界面的底部有一个checkbox:uni-app x。勾选后会新建为uni-app x项目。

uni-app x的项目,manifest.json中会多一个节点
`"uni-app-x" : {}`
。这是HBuilder识别项目类型的标记。
```
json
{
"name"
:
"hello-uniapp x"
,
"appid"
:
"__UNI__4517034"
,
"description"
:
""
,
"versionName"
:
"1.0.0"
,
"versionCode"
:
"100"
,
"uni-app-x"
:
{
}
}
```
uni-app x的项目,在左侧项目管理器的图标是圆形的U(之前是方型的U)。

## 项目结构
uni-app x的项目结构与之前基本一致。
主要的差别是没有nativeplugins目录和wxcomponents目录。原因是uni-app x不支持uni-app js引擎版的原生语言插件,不支持微信小程序wxml组件。
基于uts的插件,可以在uni-app x和uni-app上通用。
## 运行
uni-app x的真机运行基座,和uni-app js引擎版不同,是一个绿色圆形的U(之前是方型H),基座名称默认为
`uni-app x`
(之前叫HBuilder)。

-
uni-app x基座,只能运行uni-app x项目,包名是io.dcloud.uniappx
-
HBuilder基座,可以运行5+App、wap2app和uni-app js引擎版。包名是io.dcloud.HBuilder
uni-app x运行时,控制台右上角可以选择开启原生日志。
公测版带宽有限,打包自定义基座或正式包时可能更慢。
目前仅支持真机运行,不支持断点debug。
## 发行
uni-app x目前只能打包apk。
暂不支持渠道包。
不支持wgt热更新、不支持安心打包。
下载到项目下的uts插件可打包含入。但内置模块暂不支持拆除,比如video。
\ No newline at end of file
docs/uni-app-x/readme.md
浏览文件 @
bb6a05c0
...
@@ -88,7 +88,9 @@ uvue支持的vue语法,是按vue3实现的,但一期uvue不支持setup。详
...
@@ -88,7 +88,9 @@ uvue支持的vue语法,是按vue3实现的,但一期uvue不支持setup。详
uvue支持的css语法,是web的子集,类似于nvue的css。仅支持flex布局。但也足以布局出需要的界面。详见
[
css语法
](
uni-app-x/css/README.md
)
uvue支持的css语法,是web的子集,类似于nvue的css。仅支持flex布局。但也足以布局出需要的界面。详见
[
css语法
](
uni-app-x/css/README.md
)
以上约束特指App端的uvue引擎。如果把uvue页面编译到小程序和web平台,它的script仍然会被编译为js、它的样式遵循web的样式定义。
以上约束特指App端的uvue引擎。如果把uvue页面编译到小程序和web平台,它的script仍然会被编译为js、web的样式也都可以使用。
更多示例代码参考:
[
hello uni-app x
](
https://gitcode.net/dcloud/hello-uni-app-x
)
## 3. uni的组件
## 3. uni的组件
...
@@ -262,30 +264,6 @@ uni-app js版的“App原生语言插件”无法在 uni-app x 中运行。
...
@@ -262,30 +264,6 @@ uni-app js版的“App原生语言插件”无法在 uni-app x 中运行。
欢迎去
[
需求墙
](
https://vote.dcloud.net.cn/#/?name=uni-app%20x
)
投票,告诉我们你的需求优先级。
欢迎去
[
需求墙
](
https://vote.dcloud.net.cn/#/?name=uni-app%20x
)
投票,告诉我们你的需求优先级。
## 项目标识和区别
在HBuilder3.9起,新建uni-app项目界面的底部有一个checkbox:uni-app x。勾选后会新建为uni-app x项目。
uni-app x的项目,manifest.json中会多一个节点
`"uni-app-x" : {}`
。这是HBuilder识别项目类型的标记。
```
json
{
"name"
:
"hello-uniapp x"
,
"appid"
:
"__UNI__4517034"
,
"description"
:
""
,
"versionName"
:
"1.0.0"
,
"versionCode"
:
"100"
,
"uni-app-x"
:
{
}
}
```
uni-app x的项目,在左侧项目管理器的图标是圆形的U(之前是方型的U)。

uni-app x的真机运行基座,和uni-app js引擎版不复用,是一个绿色圆形的U(之前是方型H),基座名称默认为
`uni-app x`
(之前叫HBuilder)。
HBuilder基座可以运行5+App、wap2app和uni-app js引擎版。uni-app x基座只能运行uni-app x项目。
## 自动化测试
## 自动化测试
uni-app x 从源头重视产品质量,第一个版本就支持自动化测试。并为uni-app x产品编写了数万行自动化测试例代码。
uni-app x 从源头重视产品质量,第一个版本就支持自动化测试。并为uni-app x产品编写了数万行自动化测试例代码。
...
@@ -349,7 +327,7 @@ uvue的script里写的就是uts,uts就可以直接调原生代码。无所谓
...
@@ -349,7 +327,7 @@ uvue的script里写的就是uts,uts就可以直接调原生代码。无所谓
是的。为三方ide做插件是一个投资大且充满不确定性的事情,官方有限精力会聚焦在自身产品优化上。
是的。为三方ide做插件是一个投资大且充满不确定性的事情,官方有限精力会聚焦在自身产品优化上。
-
uni-app x 支持最低的Android版本多少?
-
uni-app x 支持最低的Android版本多少?
Android 5+
。Android4.4可能也可以运行,但官方发版前不会对4.4测试。
Android 5+
-
未来 uni-app js引擎版还维护吗?
-
未来 uni-app js引擎版还维护吗?
维护。服务js开发者仍然是DCloud的重点。但nvue和5+将不再维护。
维护。服务js开发者仍然是DCloud的重点。但nvue和5+将不再维护。
...
...
docs/uni-app-x/static/newproject.png
0 → 100644
浏览文件 @
bb6a05c0
44.9 KB
docs/uni-app-x/static/playground.jpg
0 → 100644
浏览文件 @
bb6a05c0
39.7 KB
docs/uni-app-x/tutorial/request.md
浏览文件 @
bb6a05c0
...
@@ -18,11 +18,12 @@ uni.request({
...
@@ -18,11 +18,12 @@ uni.request({
但在uts等强类型语言中无法这样,会报resData[0]无法安全访问、没有plugin_name属性,因为resData是个可为空的any类型,你确实没有为它定义过任何属性。
但在uts等强类型语言中无法这样,会报resData[0]无法安全访问、没有plugin_name属性,因为resData是个可为空的any类型,你确实没有为它定义过任何属性。
在uts中,提供了2种方案:
在uts中,提供了2种方案:
1.
使用
[
UTSJSONObject
](
../..
/uts/data-type.md#UTSJSONObject
)
,不需要提前为json数据定义类型,在使用中通过下标访问并动态转换类型
1.
使用
[
UTSJSONObject
](
/uts/data-type.md#UTSJSONObject
)
,不需要提前为json数据定义类型,在使用中通过下标访问并动态转换类型
2.
使用
[
type
](
../..
/uts/data-type.md#type
)
,提前定义json数据类型,在request时通过泛型传入类型,拿到的就是一个有类型的对象,之后的用法和js一样
2.
使用
[
type
](
/uts/data-type.md#type
)
,提前定义json数据类型,在request时通过泛型传入类型,拿到的就是一个有类型的对象,之后的用法和js一样
## 方式1:UTSJSONObject
## 方式1:UTSJSONObject
UTSJSONObject是uts的内置对象,它无法使用
`.操作符`
,但可以用下标和keypath来访问json数据。
UTSJSONObject是uts的内置对象,它无法使用
`.操作符`
,但可以用下标和keypath来访问json数据。
### UTSJSONObject下标方式
```
ts
```
ts
// uts写法
// uts写法
// 假使服务器返回的json数据是:{code:0,data:[{"plugin_name":"插件名称A"}]}
// 假使服务器返回的json数据是:{code:0,data:[{"plugin_name":"插件名称A"}]}
...
@@ -43,7 +44,25 @@ uni.request({
...
@@ -43,7 +44,25 @@ uni.request({
上面代码中打印日志部分是为了方便初学者理解,实际开发时代码行数不会多几行,主要是多几次as做类型转换。
上面代码中打印日志部分是为了方便初学者理解,实际开发时代码行数不会多几行,主要是多几次as做类型转换。
更多详见
[
UTSJSONObject
](
../../uts/data-type.md#UTSJSONObject
)
### UTSJSONObject keypath方式
上面的写法是每层数据都as,通过下标来访问。UTSJSONObject还支持keypath,这是一种可穿透多层数据访问的写法,传入一个path字符串,返回相应数据。
```
ts
// uts写法
// 假使服务器返回的json数据是:{code:0,data:[{"plugin_name":"插件名称A"}]}
uni
.
request
({
url
:
"
https://ext.dcloud.net.cn/plugin/uniappx-plugin-list
"
,
success
:
(
res
)
=>
{
let
resData
=
res
.
data
as
UTSJSONObject
if
(
resData
!=
null
)
{
console
.
log
(
resData
.
getString
(
"
data[0].plugin_name
"
))
//直接访问data属性的第一个数组项目里的plugin_name属性
}
}
})
```
除了getString,还有getNumber、getBoolean、getJSON、getArray、getAny。只要keypath的路径输入正确、类型正确,就可以取得值。当然path没有代码提示。
更多详见
[
UTSJSONObject
](
/uts/data-type.md#UTSJSONObject
)
## 方式2:type和泛型
## 方式2:type和泛型
...
@@ -80,7 +99,7 @@ type IRootType = {
...
@@ -80,7 +99,7 @@ type IRootType = {
因type不可嵌套,生成了2个type。注意顺序,Data这个type需写在前面,因为后面要引用它。引用代码执行时如未定义该类型,会报错。
因type不可嵌套,生成了2个type。注意顺序,Data这个type需写在前面,因为后面要引用它。引用代码执行时如未定义该类型,会报错。
-
第二步:把这段类型定义,放在
`<script>`
根下,也就是export default{}之前。然后给uni.request传入泛型参数
`<IRootType>`
,返回的res自动转换好了类型,可以直接
`.`
属性了。
-
第二步:把这段类型定义,放在
`<script>`
根下,也就是export default{}之前。然后给uni.request传入泛型参数
`<IRootType>`
,返回的res
.data
自动转换好了类型,可以直接
`.`
属性了。
**注意:**
因为
`res.data`
是对象,所以泛型那里直接使用
`<IRootType>`
。有的服务器接口返回的
`res.data`
是数组,就需要在泛型那里写成
`<IRootType[]>`
**注意:**
因为
`res.data`
是对象,所以泛型那里直接使用
`<IRootType>`
。有的服务器接口返回的
`res.data`
是数组,就需要在泛型那里写成
`<IRootType[]>`
...
@@ -114,7 +133,7 @@ type IRootType = {
...
@@ -114,7 +133,7 @@ type IRootType = {
</
script
>
</
script
>
```
```
与UTSJSONObject方式相比,
不用使用as做很多转换,
虽然需要定义type,但由于有工具可以自动生成type,所以整体使用体验,比UTSJSONObject方式方便一点。
与UTSJSONObject方式相比,
type方式在使用数据时可以使用
`.操作符`
,有代码提示。
虽然需要定义type,但由于有工具可以自动生成type,所以整体使用体验,比UTSJSONObject方式方便一点。
type+泛型这个方式,也是ts开发者惯用的方式。
type+泛型这个方式,也是ts开发者惯用的方式。
...
@@ -134,11 +153,11 @@ type DataType = {
...
@@ -134,11 +153,11 @@ type DataType = {
有了这个类型,再给它json数据进行实例化,就达到了给json数据定义类型的目标。给json数据定义好类型,就可以自由的使用
`.操作符`
获取属性了。
有了这个类型,再给它json数据进行实例化,就达到了给json数据定义类型的目标。给json数据定义好类型,就可以自由的使用
`.操作符`
获取属性了。
详见
[
type
](
../..
/uts/data-type.md#type
)
详见
[
type
](
/uts/data-type.md#type
)
而泛型,是一个对方法参数进行通用的类型描述。它告诉一个支持泛型的方法,给方法传入什么类型,方法就会返回什么类型。
而泛型,是一个对方法参数进行通用的类型描述。它告诉一个支持泛型的方法,给方法传入什么类型,方法就会返回什么类型。
不过uts的泛型支持还没有达到ts的泛型完善度,详见
[
泛型
](
../..
/uts/generics.md
)
不过uts的泛型支持还没有达到ts的泛型完善度,详见
[
泛型
](
/uts/generics.md
)
uni.request方法是支持泛型的,这意味着返回结果可以有很多种类型。
uni.request方法是支持泛型的,这意味着返回结果可以有很多种类型。
...
@@ -162,13 +181,13 @@ type DataType = {
...
@@ -162,13 +181,13 @@ type DataType = {
}
}
```
```
如您不了解null的安全使用,
[
详见
](
../..
/uts/data-type.md#null
)
如您不了解null的安全使用,
[
详见
](
/uts/data-type.md#null
)
-
务必注意res.data返回的是对象还是数组
-
务必注意res.data返回的是对象还是数组
如果res.data返回的是对象,那么泛型调用时直接
`uni.request<IRootType>(`
如果res.data返回的是对象,那么泛型调用时直接
`uni.request<IRootType>(`
如果res.data返回的是数组,那么传泛型时必须传入数组格式
`uni.request<IRootType[]>(`
如果res.data返回的是数组,那么传泛型时必须传入数组格式
`uni.request<IRootType[]>(`
,注意多了一个
`[]`
-
type的敏感词转义
-
type的敏感词转义
...
@@ -176,16 +195,15 @@ type DataType = {
...
@@ -176,16 +195,15 @@ type DataType = {
比如
`{"a:b":"123","a-b":"456"}`
,这些键名对于type来讲都是非法的。转换type就会失败。
比如
`{"a:b":"123","a-b":"456"}`
,这些键名对于type来讲都是非法的。转换type就会失败。
如果你的服务器数据涉及这类问题且数据格式不可改,那只能改用UTSJSONObject方式。
hx的json转type工具,会对一些敏感符合和关键字自动转义。但也有无法转移的符号和词,详见:
[
type
](
/uts/data-type.md#JSON_FIELD
)
特殊词清单详见:
[
type
](
../../uts/data-type.md#type
)
如果你的服务器数据涉及这类问题且数据格式不可改,那只能改用UTSJSONObject方式。
### 完整实例
### 完整实例
再举一个实际中更常见的例子。联网获取插件市场的插件列表数据,并绑定在模板上,还可以翻页。
再举一个实际中更常见的例子。联网获取插件市场的插件列表数据,并绑定在模板上,还可以翻页。
翻页需要用到
[
...展开操作符
](
../..
/uts/operator.md#展开语法...
)
翻页需要用到
[
...展开操作符
](
/uts/operator.md#展开语法...
)
```
vue
```
vue
<
template
>
<
template
>
...
...
docs/uts/data-type.md
浏览文件 @
bb6a05c0
...
@@ -1056,12 +1056,14 @@ let rect = {
...
@@ -1056,12 +1056,14 @@ let rect = {
-
仅限于web和Android,在iOS上swift不支持
`.`
操作符。
-
仅限于web和Android,在iOS上swift不支持
`.`
操作符。
-
在Android上也只支持字面量定义json(因为类型可推导)。如果是
`JSON.parse()`
转换的,则不能使用。
-
在Android上也只支持字面量定义json(因为类型可推导)。如果是
`JSON.parse()`
转换的,则不能使用。
2.
`[""]`
下标
属性
2.
`[""]`
下标
即
`rect["x"]`
。
即
`rect["x"]`
。
这是一种通用的方式,不管通过字面量定义的 UTSJSONObject,还是通过
`JSON.parse()`
,不管是 web、Android、iOS 哪个平台,都可以使用下标方式访问 UTSJSONObject 属性。
这是一种通用的方式,不管通过字面量定义的 UTSJSONObject,还是通过
`JSON.parse()`
,不管是 web、Android、iOS 哪个平台,都可以使用下标方式访问 UTSJSONObject 属性。
但下标返回嵌套的 UTSJSONObject 时,用起来比较麻烦,因为无法判断嵌套节点是对象还是数组,需要再 `as` 才能继续使用下一层数据。
但下标返回的数据,类型是any,想继续使用需要`as`为具体类型。
尤其是有子对象时,需要 `as` 后才能继续访问下一层数据。
```
ts
```
ts
let
rect
=
{
let
rect
=
{
...
@@ -1093,7 +1095,7 @@ console.log((rect["border"] as UTSJSONObject[])[0]["color"]); // red
...
@@ -1093,7 +1095,7 @@ console.log((rect["border"] as UTSJSONObject[])[0]["color"]); // red
```
```
如果是
`JSON.parse`
解析的数
组,目前只能通过下标访问,无法使用
`.`
操作符
。
如果是
`JSON.parse`
解析的数
据,只能通过下标访问,无法使用
`.`
操作符。因为
`.`
操作符的成立建立在编译器可确定类型的前提,字面量直接赋值可识别类型,
`JSON.parse`
无法识别类型
。
```
ts
```
ts
let
listData
=
JSON
.
parse
(
`{"result":true, "count":42}`
)
as
UTSJSONObject
let
listData
=
JSON
.
parse
(
`{"result":true, "count":42}`
)
as
UTSJSONObject
...
@@ -1102,19 +1104,19 @@ console.log(listData["count"]); //42
...
@@ -1102,19 +1104,19 @@ console.log(listData["count"]); //42
console
.
log
(
listArr
[
0
][
"
title
"
]);
//第一组
console
.
log
(
listArr
[
0
][
"
title
"
]);
//第一组
```
```
多层级下标访问时需要使用 as 转换为 UTSJSONObject
多层级下标访问时需要使用 as 转换为 UTSJSONObject
或 UTSJSONObject[]
```
ts
```
ts
var
j
=
{
var
j
=
{
"
test
"
:{
"
subobj
"
:{
"
a
-b
"
:
1
"
a
bc
"
:
1
}
}
}
}
console
.
log
((
j
[
'
test
'
]
as
UTSJSONObject
)[
'
a-b
'
]);
console
.
log
((
j
[
'
subobj
'
]
as
UTSJSONObject
)[
'
abc
'
]);
```
```
1
.
通过 keyPath 访问 UTSJSONObject 数据
3
.
通过 keyPath 访问 UTSJSONObject 数据
在
`HBuilderX`
3.9.0 之后的版本,UTSJSONObject 提供了另外一种属性访问方式,
keyPath。如果你了解 XPath、JSONPath 的话,这个概念类似。
`HBuilderX`
3.9+,UTSJSONObject 提供了另外一种属性访问方式:
keyPath。如果你了解 XPath、JSONPath 的话,这个概念类似。
keypath是把
`.`
操作符作为一个字符串传入了UTSJSONObject的一个方法中,比如
`utsObj.getString("address.detailInfo.street")`
keypath是把
`.`
操作符作为一个字符串传入了UTSJSONObject的一个方法中,比如
`utsObj.getString("address.detailInfo.street")`
...
@@ -1140,24 +1142,29 @@ let utsObj = {
...
@@ -1140,24 +1142,29 @@ let utsObj = {
我们可以通过 getString/getNumber/getBoolean/getJSON/getAny 等函数获得指定类型的属性,如果属性不存在,则返回null
我们可以通过 getString/getNumber/getBoolean/getJSON/getAny 等函数获得指定类型的属性,如果属性不存在,则返回null
```
ts
```
ts
// 打印结果:zhangsan
console
.
log
(
utsObj
.
getString
(
"
username
"
))
// 打印结果:zhangsan
console
.
log
(
utsObj
.
getString
(
"
username
"
))
console
.
log
(
utsObj
.
getNumber
(
"
age
"
))
// 打印结果:12
// 打印结果:12
console
.
log
(
utsObj
.
getJSON
(
"
address
"
))
// 打印结果:[object]
console
.
log
(
utsObj
.
getNumber
(
"
age
"
))
console
.
log
(
utsObj
.
getBoolean
(
"
isStudent
"
))
// 打印结果:false
// 打印结果:[object]
console
.
log
(
utsObj
.
getString
(
"
一个不存在属性
"
))
// 打印结果:null
console
.
log
(
utsObj
.
getJSON
(
"
address
"
))
```
// 打印结果:false
console
.
log
(
utsObj
.
getBoolean
(
"
isStudent
"
))
// 打印结果:null
console
.
log
(
utsObj
.
getString
(
"
一个不存在属性
"
))
需要特别注意的是:属性名 和 属性类型,都要正确,否则不会返回对应的属性结果
```
ts
console
.
log
(
utsObj
.
getNumber
(
"
age
"
))
// 打印结果:12
console
.
log
(
utsObj
.
getNumber
(
"
agee
"
))
// 名字不对,打印结果:null
console
.
log
(
utsObj
.
getString
(
"
age
"
))
// 类型不对,打印结果:null
```
```
为了更方便的访问 UTSJSONObject 中包含的数组中的元素,还可以通过 keyPath 指定数组下标来访问 UTSJSONObject 中的数据, 支持多维数组的访问。
keypath的一大优势就是可以深入数据层级,如下:
```
ts
```
ts
console
.
log
(
utsObj
.
getString
(
"
address.detailInfo.street
"
))
// 结果:the wall street
```
如果数据里包括数组、多维数组,也可以穿透下去获取数据,如下:
```
ts
let
obj
=
{
let
obj
=
{
"
data
"
:
[{
"
data
"
:
[{
"
a
"
:
"
1
"
"
a
"
:
"
1
"
...
@@ -1173,28 +1180,12 @@ let obj = {
...
@@ -1173,28 +1180,12 @@ let obj = {
]
]
}
}
// 打印结果:1
console
.
log
(
obj
.
getString
(
'
data[0].a
'
))
// 打印结果:1
console
.
log
(
obj
.
getString
(
'
data[0].a
'
))
console
.
log
(
obj
.
getNumber
(
'
data[1].a
'
))
// 打印结果:2
// 打印结果:2
console
.
log
(
obj
.
getBoolean
(
'
data[2][0].b
'
))
// 打印结果:true
console
.
log
(
obj
.
getNumber
(
'
data[1].a
'
))
console
.
log
(
obj
.
getJSON
(
'
data[2][1]
'
))
// 打印结果:{"b":"test"}
// 打印结果:true
console
.
log
(
obj
.
getArray
(
'
data[3]
'
))
// 打印结果:[1, 2, 3]
console
.
log
(
obj
.
getBoolean
(
'
data[2][0].b
'
))
console
.
log
(
obj
.
getAny
(
'
data[1].a
'
))
// 打印结果:2
// 打印结果:{"b":"test"}
console
.
log
(
obj
.
getJSON
(
'
data[2][1]
'
))
// 打印结果:[1, 2, 3]
console
.
log
(
obj
.
getArray
(
'
data[3]
'
))
// 打印结果:2
console
.
log
(
obj
.
getAny
(
'
data[1].a
'
))
```
这种绑定类型的这对于原生开发者来说比较熟悉。但是需要特别注意的是: 如果属性名正确,但是属性类型不符合,那么不会返回对应的属性结果
```
ts
// 打印结果:12
console
.
log
(
utsObj
.
getNumber
(
"
age
"
))
// 打印结果:null
console
.
log
(
utsObj
.
getString
(
"
age
"
))
```
```
...
@@ -1209,26 +1200,9 @@ console.log(utsObj.getAny("age") as Number)
...
@@ -1209,26 +1200,9 @@ console.log(utsObj.getAny("age") as Number)
console
.
log
(
utsObj
.
getAny
(
"
address
"
)
as
UTSJSONObject
)
console
.
log
(
utsObj
.
getAny
(
"
address
"
)
as
UTSJSONObject
)
```
```
在传统的属性访问中,UTSJSONObject 的嵌套是一种比较复杂的情况,需要我们层层解析才能获取数据:
除了直接使用UTSJSONObject外,在 uts 中使用json数据还有2种方式:
1.
UTSJSONObject.toMap() 转为Map对象
[
见上
](
#Map
)
```
ts
2.
把json字符串或对象字面量通过type转为自定义类型,这是ts里经常使用的方式
[
见下
](
#type
)
// 获取 utsObj 中的 address属性
let
addressObj
=
utsObj
[
"
address
"
]
as
UTSJSONObject
// 获取 address 中的 detail 属性
let
detailInfoObj
=
utsObj
[
"
detailInfo
"
]
as
UTSJSONObject
// 结果:the wall street
let
street
=
utsObj
[
"
street
"
]
as
String
```
上面的写法,啰嗦且容易出错。因此,我们提供了更易用的 keyPath 写法,帮助开发者摆脱复杂的对象嵌套关系:
```
ts
// 结果:the wall street
let
street
=
utsObj
.
getString
(
"
address.detailInfo.street
"
)
```
当然,除了直接使用UTSJSONObject外,在 uts 中使用json数据还有2种方式:
1.
UTSJSONObject.toMap() 转为Map对象
[
见下
](
#Map
)
2.
把json字符串或对象字面量通过type转为自定义类型,这是ts里经常使用的方式
[
详见
](
type-aliases.md
)
### 更多API
### 更多API
...
@@ -1286,36 +1260,6 @@ console.log(person.name) //返回zhangsan
...
@@ -1286,36 +1260,6 @@ console.log(person.name) //返回zhangsan
但在uts中,由于interface的概念在kotlin和swift有其他用途,所以uts中推荐开发者把json转成一个type,而不是interface。
但在uts中,由于interface的概念在kotlin和swift有其他用途,所以uts中推荐开发者把json转成一个type,而不是interface。
### type 类型的遍历
我们为每个自定义 type 类型提供了迭代器,可以使用 for-in 遍历出 type 类型中的所有属性名
```
ts
let
person
:
PersonType
=
{
id
:
1
,
name
:
"
zhangsan
"
,
age
:
18
}
for
(
key
in
person
)
{
console
.
log
(
key
)
// 输出 "id", "name", "age"
}
```
### type 类型的下标访问
我们为每个自定义 type 类型提供了下标操作,在适当的时机,可以使用下标的方式来读取或者修改 type 类型的属性值。
-
注意:由于通过下标修改属性值,编译阶段不会对下标操作的key值进行校验,所以可能会存在运行期代码失效的情况。为了代码安全,除非在必要时才进行通过下标修改属性的操作。
```
ts
let
person
:
PersonType
=
{
id
:
1
,
name
:
"
zhangsan
"
,
age
:
18
}
console
.
log
(
person
[
"
id
"
])
//1
obj
[
"
age
"
]
=
25
console
.
log
(
obj
[
"
age
"
])
//25
console
.
log
(
obj
.
age
)
//25
```
> 特别说明:
> type 类型的遍历和下标访问功能自 HBuilderX3.9.0 开始提供。
### 把json数组转为type
### 把json数组转为type
上面的例子中,数据是json对象,下面再来定义一个json数组。
上面的例子中,数据是json对象,下面再来定义一个json数组。
...
@@ -1473,8 +1417,13 @@ console.log(person.name); // 返回zhangsan
...
@@ -1473,8 +1417,13 @@ console.log(person.name); // 返回zhangsan
使用!断言,是强制编译器信任开发者的写法,编译器放过后,在运行期一旦person为null,调用
`person.name`
就会崩溃。而使用
`person?.name`
则不会崩溃,只会返回null。
使用!断言,是强制编译器信任开发者的写法,编译器放过后,在运行期一旦person为null,调用
`person.name`
就会崩溃。而使用
`person?.name`
则不会崩溃,只会返回null。
**特殊情况**
#### 敏感字和符号@JSON_FIELD
在定义Type时键名必须符合变量命名规则(如第一个字符不能数字,不能包含空格或运算符,不能使用语言保留的关键字等),如果json字符串中的键名不符合变量命名规则,需要添加注释
`@JSON_FIELD`
定义键名转换规则才能通过JSON.parse解析转type。
在定义Type时键名必须符合变量命名规则(如第一个字符不能数字,不能包含空格或运算符,不能使用语言保留的关键字等),
如果json字符串中的键名不符合变量命名规则,比如有个key的名字叫"a+b",这种json转type会失败。
解决方案是,添加注释
`@JSON_FIELD`
定义键名转换规则,才能通过JSON.parse解析转type。
```
ts
```
ts
type
ExampleType
=
{
type
ExampleType
=
{
/**
/**
...
@@ -1485,15 +1434,17 @@ type ExampleType = {
...
@@ -1485,15 +1434,17 @@ type ExampleType = {
a_b
:
string
a_b
:
string
}
}
```
```
以上示例定义的 ExampleType 类型,在
`a_b: string`
声明时添加注释
`@JSON_FIELD "a+b"`
,表示 JSON.parse 时会将json字符中的键名"a+b"转换为ExampleType类型的"a_b"属性;JSON.stringify 时会将ExampleType类型的"a_b"属性转换为json字符串中的"a+b"键名。
以上示例定义的 ExampleType 类型,在
`a_b: string`
声明时添加注释
`@JSON_FIELD "a+b"`
,表示:
-
JSON.parse 时会将json字符中的键名"a+b"转换为ExampleType类型的"a_b"属性;
-
JSON.stringify 时会将ExampleType类型的"a_b"属性转换为json字符串中的"a+b"键名。
推荐的转换规则如下:
推荐的转换规则如下:
-
将不合法的字符(如空格、运算符等)转换为下划线“_”,如“a+b”转换为“a_b”
-
将不合法的字符(如空格、运算符等)转换为下划线“_”,如“a+b”转换为“a_b”
-
将保留
[
关键词
](
keywords.md
)
(如class、enum等)转换时,在前面添加下划线,如“class”转换为“_class”
-
将保留
[
关键词
](
keywords.md
)
(如class、enum等)转换时,在前面添加下划线,如“class”转换为“_class”
-
如果转换后的名称已存在,在后面添加下划线
“_”避免冲突,如同时存在“a+b”和“a-b”,分别转换为“a_b”和“a_b_”
-
如果转换后的名称已存在,在后面添加下划线
`_`
避免冲突,如同时存在“a+b”和“a-b”,分别转换为
`a_b`
和
`a_b_`
以下举例json字符串
“{"a+b":"addition value","a-b":"subtraction value","class":"classification value"}”
,应该如何定义 type 才能使用 JSON.parse 转换
以下举例json字符串
`{"a+b":"addition value","a-b":"subtraction value","class":"classification value"}`
,应该如何定义 type 才能使用 JSON.parse 转换
```
ts
```
ts
type
SpecialType
=
{
type
SpecialType
=
{
/**
/**
...
@@ -1529,9 +1480,9 @@ console.log(JSON.stringify(t)) //输出: {"a+b":"value 1","a-b":"value 2","class
...
@@ -1529,9 +1480,9 @@ console.log(JSON.stringify(t)) //输出: {"a+b":"value 1","a-b":"value 2","class
#### json转type工具
#### json转type工具
如果json数据属性较多、嵌套较多,那么为json数据编写type类型定义,也是一件繁琐的事情。
如果json数据属性较多、嵌套较多
、还涉及转义
,那么为json数据编写type类型定义,也是一件繁琐的事情。
HBuilderX 3.9起内置了一个json转type工具,在
`json编辑器`
中选择一段内容点右键,选择
`json转type`
,即可根据json数据内容自动推导生成type定义。
HBuilderX 3.9起内置了一个json转type工具,在
`json编辑器`
中选择一段内容点右键,选择
`json转type`
,即可根据json数据内容自动推导生成type定义
,如果json内容涉及转义,工具也会自动转义
。


...
@@ -1566,7 +1517,39 @@ uvue文件中data中的json数据也涉及类型定义。此时注意:type定
...
@@ -1566,7 +1517,39 @@ uvue文件中data中的json数据也涉及类型定义。此时注意:type定
大多数情况下,data里的json数据是空的,联网从服务器取到一段json字符串,然后再赋值并转type。
大多数情况下,data里的json数据是空的,联网从服务器取到一段json字符串,然后再赋值并转type。
由于篇幅较长,示例另见:
[
request
](
../uni-app-x/tutorial/request.md
)
由于篇幅较长,示例另见:
[
request教程
](
../uni-app-x/tutorial/request.md
)
### type 类型的遍历
> HBuilderX3.9+
uts 为自定义 type 类型提供了迭代器,可以使用 for-in 遍历出 type 类型中的所有属性名
```
ts
let
person
:
PersonType
=
{
id
:
1
,
name
:
"
zhangsan
"
,
age
:
18
}
for
(
key
in
person
)
{
console
.
log
(
key
)
// 输出 "id", "name", "age"
}
```
### type 类型的下标访问
> HBuilderX3.9+
uts 为自定义 type 类型提供了下标操作,在适当的时机,可以使用下标的方式来读取或者修改 type 类型的属性值。
-
注意:由于通过下标修改属性值,编译阶段不会对下标操作的key值进行校验,所以可能会存在运行期代码失效的情况。为了代码安全,除非在必要时才进行通过下标修改属性的操作。
```
ts
let
person
:
PersonType
=
{
id
:
1
,
name
:
"
zhangsan
"
,
age
:
18
}
console
.
log
(
person
[
"
id
"
])
//1
obj
[
"
age
"
]
=
25
console
.
log
(
obj
[
"
age
"
])
//25
console
.
log
(
obj
.
age
)
//25
```
## 其他
## 其他
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录