Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
G8866
unidocs-zh
提交
f24ae135
unidocs-zh
项目概览
G8866
/
unidocs-zh
与 Fork 源项目一致
Fork自
DCloud / unidocs-zh
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
unidocs-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f24ae135
编写于
9月 04, 2023
作者:
W
wanganxp
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
x
上级
d58acf64
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
299 addition
and
3 deletion
+299
-3
docs/uni-app-x/_sidebar.md
docs/uni-app-x/_sidebar.md
+3
-1
docs/uni-app-x/api/request.md
docs/uni-app-x/api/request.md
+8
-1
docs/uni-app-x/tutorial/codegap.md
docs/uni-app-x/tutorial/codegap.md
+3
-1
docs/uni-app-x/tutorial/request.md
docs/uni-app-x/tutorial/request.md
+285
-0
未找到文件。
docs/uni-app-x/_sidebar.md
浏览文件 @
f24ae135
*
[
概述
](
README.md
)
*
[
开发注意
](
codegap.md
)
*
教程
*
[
与js开发的差别
](
tutorial/codegap.md
)
*
[
request联网教程
](
tutorial/request.md.md
)
*
[
编译器
](
compiler/README.md
)
*
全局文件
*
[
main.uts
](
/collocation/main.md
)
...
...
docs/uni-app-x/api/request.md
浏览文件 @
f24ae135
...
...
@@ -2,6 +2,10 @@
<!-- UTSAPIJSON.request.description -->
request方法支持泛型,可将服务器的json数据转为自定义的type。
由于json在强类型语言中无法像js那样使用,如果您不熟悉ts中type+泛型来格式化服务器返回的数据,那么需要点这里阅读
[
request的教程
](
../tutorial/request.md
)
<!-- UTSAPIJSON.request.param -->
<!-- UTSAPIJSON.request.returnValue -->
...
...
@@ -12,4 +16,7 @@
<!-- UTSAPIJSON.general_type.name -->
<!-- UTSAPIJSON.general_type.param -->
\ No newline at end of file
<!-- UTSAPIJSON.general_type.param -->
## tips
-
uts中暂不支持arraybuffer
\ No newline at end of file
docs/uni-app-x/codegap.md
→
docs/uni-app-x/
tutorial/
codegap.md
浏览文件 @
f24ae135
...
...
@@ -120,7 +120,7 @@ data里`:`的用途是赋值,无法通过`:`定义类型,所以data的数据
export
default
{
data
()
{
return
{
// 必须写这里
}
}
}
...
...
@@ -175,6 +175,8 @@ uts中有2种方式使用json数据:
1.
把json数据转为type,自定义一个类型,声明json数据内容中每个属性的类型。然后就可以使用对象属性的方式来使用json数据。
[
详见
](
../uts/data-type.md#type
)
2.
使用UTSJSONObject,不为json定义类型,然后通过下标和方法来使用json数据。
[
详见
](
../uts/data-type.md#ustjsonobject
)
如果是联网获取服务器发下的json数据,那么
**务必需要读教程**
[
request
](
tutorial/request.md
)
## 函数参数类型
如果函数参数为基础数据类型,函数调用时,参数类型可以省略,编译器会自动推导。
\
...
...
docs/uni-app-x/tutorial/request.md
0 → 100644
浏览文件 @
f24ae135
# 联网
在js环境中,服务器下发的字符串,通过uni.request获取后,会默认转成json对象,开发者可以通过
`.操作符`
获取对象的属性,绑定到界面上。
```
js
// js写法
// 假使服务器返回的json数据是:{code:0,data:[{"plugin_name":"插件名称A"}]}
// 这是一个对象,拥有code、data这2个子属性,data属性的值是一个数组,该数组内又有若干子对象,子对象有属性`plugin_name`。
uni
.
request
({
url
:
"
https://ext.dcloud.net.cn/plugin/uniappx-plugin-list
"
,
success
:
(
res
)
=>
{
let
resData
=
res
.
data
.
data
console
.
log
(
resData
[
0
].
plugin_name
)
// resData是一个js对象数组,通过下标拿到第一个对象,然后通过.来访问对象的plugin_name属性
}
})
```
但在uts等强类型语言中无法这样,会报resData[0]无法安全访问、没有plugin_name属性,因为resData是个可为空的any类型,你确实没有为它定义过任何属性。
在uts中,提供了2种方案:
1.
使用
[
UTSJSONObject
](
../../uts/data-type.md#UTSJSONObject
)
,不需要提前为json数据定义类型,在使用中通过下标访问并动态转换类型
2.
使用
[
type
](
../../uts/data-type.md#type
)
,提前定义json数据类型,在request时通过泛型传入类型,拿到的就是一个有类型的对象,之后的用法和js一样
## 方式1:UTSJSONObject
UTSJSONObject是uts的内置对象,它无法使用
`.操作符`
,但可以用下标和keypath来访问json数据。
```
ts
// uts写法
// 假使服务器返回的json数据是:{code:0,data:[{"plugin_name":"插件名称A"}]}
uni
.
request
({
url
:
"
https://ext.dcloud.net.cn/plugin/uniappx-plugin-list
"
,
success
:
(
res
)
=>
{
console
.
log
(
res
.
data
)
// 这是一个any类型,不能直接使用
console
.
log
(
res
.
data
as
UTSJSONObject
)
// 需要把这个any类型,as成UTSJSONObject类型
console
.
log
(
res
.
data
as
UTSJSONObject
[
"
data
"
])
//UTSJSONObject支持通过下标访问属性data,但返回的仍然是any类型
let
resData
=
(
res
.
data
as
UTSJSONObject
)[
"
data
"
]
as
UTSJSONObject
[]
// as成UTSJSONObject数组
if
(
resData
!=
null
)
{
console
.
log
((
resData
[
0
])
// 访问数组的第一个数组项目,仍然是any类型,仍然需要转换
console
.
log
((
resData
[
0
]
as
UTSJSONObject
)[
"
plugin_name
"
])
// 转为UTSJSONObject后通过下标访问plugin_name属性
}
}
})
```
上面代码中打印日志部分是为了方便初学者理解,实际开发时代码行数不会多几行,主要是多几次as做类型转换。
更多详见
[
UTSJSONObject
](
../../uts/data-type.md#UTSJSONObject
)
## 方式2:type和泛型
为json数据定义一个type的自定义类型,明确好对象的属性名称及类型,然后把这个type通过泛型传给request方法,res拿出来的就是转换好的类型,就可以直接
`.操作符`
获取属性了。。
先不讲原理,先给个使用范例,然后再解读原理。
-
第一步:用HBuilderX自带的工具,给服务器数据定义类型
把服务器端返回的json数据,复制黏贴到HBuilderX的json编辑器里,点右键,转type。
![](
../static/json2type.png
)
> 转换功能需要HBuilderX 3.9+、安装了uni-app x真机运行插件、且打开的标签卡是json编辑器。(在ctrl+t新建空白md标签卡,粘贴json数据,会自动切换成json编辑器)
上面的截图是复用了其他图片,如果我们使用这个服务器接口,服务器返回的数据内容,也就是res.data的数据是这样:
```
json
{
code:
200
,
desc:
""
,
data:
[{
"plugin_name"
:
"插件名称A"
,
"plugin_id"
:
123
}]}
```
那么使用转换工具,生成的类型定义是这样:
```
ts
type
Data
=
{
plugin_id
:
number
;
plugin_name
:
string
;
}
type
IRootType
=
{
code
:
number
;
desc
:
string
;
data
:
Data
[];
}
```
-
第二步:把这段类型定义,放在
`<script>`
根下,也就是export default{}之前。然后给uni.request传入泛型参数
`<IRootType>`
,返回的res自动转换好了类型,可以直接
`.`
属性了。
```
vue
<
script
>
type
Data
=
{
plugin_id
:
number
;
plugin_name
:
string
;
}
type
IRootType
=
{
code
:
number
;
desc
:
string
;
data
:
Data
[];
}
export
default
{
onLoad
()
{
uni
.
request
<
IRootType
>
({
// 通过
<
IRootType
>
要求request方法的返回值转为IRootType类型
url
:
"
https://ext.dcloud.net.cn/plugin/uniappx-plugin-list
"
,
success
:
(
res
)
=>
{
console
.
log
(
res
.
data
)
console
.
log
(
res
.
data
instanceof
IRootType
)
//true
console
.
log
(
res
.
data
?.
data
)
//因为联网数据不可控,转换可能失败,所以这里需要用?.的方式做安全访问
let
resData
=
res
.
data
?.
data
if
(
resData
!=
null
&&
resData
.
length
>
0
){
//判断一下数组不为空
console
.
log
(
resData
[
0
])
console
.
log
(
resData
[
0
].
plugin_name
)
}
}})
},
}
</
script
>
```
与UTSJSONObject方式相比,不用使用as做很多转换,虽然需要定义type,但由于有工具可以自动生成type,所以整体使用体验,比UTSJSONObject方式更方便。
type+泛型这个方式,也是ts开发者惯用的方式。
但不熟悉ts的开发者,可能不了解type和泛型。下面讲解下。
type就是自定义一个类型。下面定义了一个数据类型DataType,该类型有2个属性,
`plugin_id`
和
`plugin_name`
,这2个属性的类型分别是number和string。
```
ts
type
DataType
=
{
plugin_id
:
number
,
plugin_name
:
string
}
```
有了这个类型,再给它json数据进行实例化,就达到了给json数据定义类型的目标。给json数据定义好类型,就可以自由的使用
`.操作符`
获取属性了。
详见
[
type
](
../../uts/data-type.md#type
)
而泛型,是一个对方法参数进行通用的类型描述。它告诉一个支持泛型的方法,给方法传入什么类型,方法就会返回什么类型。
详见
[
泛型
](
../../uts/generics.md
)
uni.request方法是支持泛型的,这意味着返回结果可以有很多种类型。
所以可以把你定义的DataType类型通过
<T>
的方式传给uni.request方法,尖括号要写在方法名和左圆括号中间。
这个方法就会把返回的res转换为你传入的DataType类型。
下面来举例:
服务器返回的数据内容,也就是res.data的数据是这样:
```
json
{
code:
200
,
desc:
""
,
data:
[{
"plugin_name"
:
"插件名称A"
,
"plugin_id"
:
123
}]}
```
观察数据,这是一个对象,拥有code、desc、data这3个子属性,code是number类型,desc是string类型,而data的类型又是一个数组。
该数组内又是若干子对象,子对象有属性
`plugin_id`
和
`plugin_name`
等。
对于这种父子结构,我们需要定义2个类型才能描述,因为每一层都需要一个type。
-
IRootType是一级的类型,它有3个属性,其中有一个data属性,类型是另一个type data的数组方式。
-
而Data是二级数组中对象的类型,有2个属性
`plugin_id`
和
`plugin_name`
注意顺序,Data这个type需写在前面,因为后面要引用它。引用代码执行时如未定义该类型,会报错。
```
ts
// uts中为json数据定义类型
type
DataType
=
{
plugin_id
:
number
,
plugin_name
:
string
}
//定义一个DataType类型,含有number类型的plugin_id属性,和string类型的plugin_name属性
type
IRootType
=
{
code
:
number
;
desc
:
string
;
data
:
Data
[];
}
```
那为何type一定要定义在export default{}之前?
其实上面的代码,type只需要定义在uni.request方法执行前就可以。但实际开发中,type大多用于data的类型定义,
而想给data定义类型,那就得写在data的前面,也就是export default{}之前了。
再举一个实际中更常见的例子。
联网获取插件市场的插件列表数据,并绑定在模板上,还可以翻页。
```
vue
<
template
>
<list-view
style=
"flex: 1;background-color: #ffffff;"
@
scrolltolower=
"loadData"
>
<template
v-for=
"(item, index) in dataList"
:key=
"index"
>
<list-item
style=
"flex-direction: row; margin-top: 10px; padding: 10px; height: 100px;"
>
<image
:src=
"item.plugin_img_link"
style=
"width: 120px;"
></image>
<text
style=
"flex: 1;"
>
{{
item
.
plugin_name
}}
</text>
</list-item>
<list-item
key=
"loading"
v-if=
"index==dataList.length-1"
>
<text
style=
"padding: 10px; text-align: center; background-color: #f8f8f8; margin-bottom: 1px;"
>
{{
loadingText
}}
</text>
</list-item>
</
template
>
</list-view>
</template>
<
script
>
type
Data
=
{
plugin_id
:
number
;
plugin_name
:
string
;
plugin_img_link
:
string
;
plugin_intro
:
string
;
is_paid
:
number
;
collection_count
:
number
;
support_count
:
number
;
buy_count
:
number
;
download_count
:
number
;
score
:
number
;
rater_count
:
number
;
tags
:
string
[];
category_level1_name
:
string
;
category_level2_name
:
string
;
update_date
:
string
;
author_avatar_link
:
string
;
author_name
:
string
;
}
type
IRootType
=
{
code
:
number
;
desc
:
string
;
data
:
Data
[];
}
export
default
{
data
()
{
return
{
dataList
:
[]
as
Data
[],
loading
:
false
,
isEnded
:
false
,
loadingError
:
''
,
$currentPage
:
1
}
},
computed
:
{
loadingText
()
:
string
{
if
(
this
.
loading
)
{
return
"
加载中...
"
}
else
if
(
this
.
isEnded
)
{
return
"
没有更多了
"
}
else
if
(
this
.
loadingError
.
length
>
0
)
{
return
this
.
loadingError
}
else
{
return
""
}
}
},
onLoad
()
{
this
.
loadData
()
},
methods
:
{
loadData
()
{
if
(
this
.
loading
||
this
.
isEnded
)
{
return
}
this
.
loading
=
true
uni
.
request
<
IRootType
>
({
url
:
"
https://ext.dcloud.net.cn/plugin/uniappx-plugin-list
"
,
data
:
{
page
:
this
.
$currentPage
,
//当前页码
page_size
:
10
//每页列表项目数量
},
success
:
(
res
)
=>
{
const
responseData
=
res
.
data
if
(
responseData
==
null
)
{
return
}
//...是展开运算符,本句用于把联网获取的数组合并到data数组里。当第一次执行时,dataList为空,push进去了第一页的数据,后续页面也同理
this
.
dataList
.
push
(...
responseData
.
data
)
if
(
responseData
.
data
.
length
==
0
)
{
this
.
isEnded
=
true
}
else
{
this
.
$currentPage
++
}
},
fail
:
(
err
)
=>
{
this
.
loadingError
=
err
.
errMsg
},
complete
:
()
=>
{
this
.
loading
=
false
}
})
},
}
}
</
script
>
```
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录