# UTS 组件开发
本文旨在帮助开发者,使用UTS开发Uni-App平台组件功能。
## 前置条件
继续阅读文档前,开发者需要了解以下前置条件:
+ HBuilderX 3.6.15 及之后版本
+ 了解Vue 组件基本概念
+ 目前仅支持nvue
## UTS组件简介
#### 为什么使用组件
组件是一种独立,可复用的UI单元,用于单独封装和承担一定的代码逻辑,组件化可以降低项目的工程复杂度,提升可维护性
组件与插件的区别在于:前者倾向于以标签的形式 对外提供UI封装,后者倾向于以函数/类 的形式 对外提供功能封装。如果你的需求更倾向于封装能力,请移步 [UTS插件开发](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html)
组件一般适用于封装非全屏的场景,如果需要你需要封装的UI始终是全屏,那么可以考虑通过UTS开发原生页面来实现。 [UTS开发原生页面示例](https://gitcode.net/dcloud/hello-uts/-/tree/master/uni_modules/uts-nativepage)
#### 为什么使用UTS开发组件
UTS组件,即:使用UTS语言在uni平台进行组件开发的技术。
UTS组件的优势在于,它秉承了UTS的跨平台特性,统一的UTS语法,各终端不同的本地产出物。
在Android平台会被编译为会被渲染为Android原生View实例,IOS或其他终端平台也是如此。
| |uts组件 |uni原生组件 |Vue组件 |
|:------ |:-------- |:-------- |:------- |
|开发语言 |uts |java/object-c |js/ts |
|组件载体 |系统原生View对象 |系统原生View对象 |WebView内部标签 |
为了降低前端开发者的开发门槛,UTS组件采用了类Vue组件的语法,[关于Vue组件](https://cn.vuejs.org/guide/essentials/component-basics.html),但是具体的函数上会有定制,我们会在下一个章节详细介绍
## UTS组件结构解析
#### UTS组件目录结构
┌─common // 可跨端公用的uts代码。推荐,不强制
├─static // 静态资源
├─utssdk
│ ├─app-android //Android平台目录
│ │ ├─assets //Android原生assets资源目录,可选
│ │ ├─libs //Android原生库目录,可选
│ │ ├─res //Android原生res资源目录,可选
│ │ ├─AndroidManifest.xml //Android原生应用清单文件,可选
│ │ ├─config.json //Android原生配置文件
│ │ ├─index.uts //Android原生插件能力实现,可选
| | └─index.vue //Android原生组件能力实现,必选
│ ├─app-ios //iOS平台目录
│ │ ├─Frameworks //iOS原生依赖的第三方 framework 依赖库存放目录,可选
│ │ ├─Resources //iOS原生所依赖的资源文件存放目录,可选
│ │ ├─info.plist //iOS原生所需要添加到主 info.plist 文件中的配置文件,可选
│ │ ├─UTS.entitlements //iOS原生所需要添加到主工程 .entitlements 文件中的配置文件,可选
│ │ ├─config.json //iOS原生配置文件
│ │ ├─index.uts //iOS原生插件能力实现,可选
| | └─index.vue //iOS原生组件能力实现,必选
│ ├─web //web平台目录
│ │ └─index.uts
│ ├─mp-alipay // 支付宝小程序平台,可选
│ ├─mp-baidu // 百度小程序平台,可选
│ ├─mp-jd // 京东小程序平台(仅限vue2),可选
│ ├─mp-kuaishou // 快手小程序平台,可选
│ ├─mp-lark // 飞书小程序平台,可选
│ ├─mp-qq // QQ小程序平台,可选
│ ├─mp-toutiao // 字节跳动小程序平台,可选
│ ├─mp-weixin // 微信小程序平台,可选
│ ├─mp-xhs // 小红书小程序平台(仅限vue2),可选
│ ├─index.d.ts // 插件能力声明,可选
│ └─index.uts // 跨平台插件能力实现,可选
└─package.json // 插件清单文件
如上所示,UTS组件的目录结构与UTS插件基本相同
唯一的差别在于,UTS组件入口文件有两个:
+ 必选的index.vue 组件入口
+ 可选的index.uts 函数能力入口
用户如果在开发组件的同时,存在一些与组件无关的能力需要对外暴露,可以在index.uts中进行实现
大多数情况下,我们只需要开发一个index.vue 即可,如果存在多个组件,可以新建多个 xxx.vue文件
关于 index.vue 源码如何编写,我们会在下一个章节介绍
#### index.vue源码结构
下面是一个组件源码 index.vue 完整示例:
**注意**
- 目前UTS组件仅支持`export default {}`的选项式API,vue3的组合式API暂未支持。
```ts
```
index.vue 要素可以分为以下几类:
+ 配置:
name:组件的使用标签,可以省略,若省略则默认为组件名称
emits:组件允许的消息事件名称,如果没有组件消息,不需要配置
+ 属性:
props:需要由组件的使用者提供,比如一个Image组件,会需要一个path属性作为图像路径来源
watch:属性的监听实现,用来监听属性数据更新。
+ 数据:
data:组件内部数据定义,用于组件内部逻辑处理,不对外暴露
+ 方法:
methods:组件方法定义,可以通过与expose组合使用,区分对内方法和对外方法
expose:与methods 字段配合使用,用以区分组件对内方法和对外方法
+ 生命周期:
组件需要重点处理 内存创建/销毁,View载体创建/销毁 过程中的资源管理,具体参考生命周期章节
+ 内置对象:
为了方便组件开发者,UTS组件内置了部分变量与函数,具体参考内置对象与函数章节
#### 生命周期
组件开发者需要重点关注组件的生命周期,以便进行资源的初始化和回收
```mermaid
graph TD;
Create-->NVBeforeLoad;
subgraph View生命周期
NVBeforeLoad-->NVLoad;
NVLoad-->NVLoaded;
NVLoaded-->NVLayouted;
NVLayouted-->NVBeforeUnload;
end
NVBeforeUnload-->unmounted;
```
|函数名 |描述 |建议行为 |是否可选 |
|:---- |:--- |:--- |:--- |
|created |组件在内存中被创建 |开发者可以在这里执行一些需要最早执行的初始化逻辑|可选|
|NVBeforeLoad |组件对应平台的view载体,即将被创建|开发者可以在这里执行一些需要在View创建前初始化的逻辑|可选|
|NVLoad |组件view载体正在被创建实现|开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型|必须实现|
|NVLayouted |组件对应平台的view载体已布局结束 |需要在view布局结束后执行的逻辑 |可选|
|NVBeforeUnload |view载体即将被卸载 |View卸载前,需要回收资源的逻辑 |可选|
|NVUnloaded |view载体已经被卸载 |View卸载后,需要回收资源的逻辑 |可选|
|unmounted |组件在内存被销毁 |资源回收逻辑 |可选|
除上述生命周期外,还存在下列可选周期函数:
+ doMeasure:
doMeasure 用于告诉排版系统,组件自身需要的宽高,具体的调用时机由排版系统决定。
一般情况下,组件的宽高应该是由终端系统的排版引擎决定,组件开发者不需要实现此函数。
但是部分场景下,组件开发者需要自己维护宽高,则需要开发者重写此函数
[vue3 生命周期暂不支持](https://uniapp.dcloud.net.cn/tutorial/vue3-api.html#%E9%80%89%E9%A1%B9-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90)
#### 内置对象和函数
为了方便组件开发者使用,UTS 组件内部内置了下列对象:
|变量名 |类型 |简介 |平台限制 |方法&属性 |
|:------- |:-------- |:-------- |:--- |:--- |
|$el |对象 |当前View实例对象 |全部平台 |开发者在NVLoad返回的对象类型|
|$androidContext|对象 |当前组件上下文 |仅android |android平台对应Context对象|
|emit("event") |函数 |发送已注册的事件 |全部平台 ||
## 简单View的示例
本章节以 一个极简的组件开发为例,介绍说明UTS组件开发流程
#### 创建插件
在HBuilder X 中选中Uni-App项目下 uni_modules目录
todo 目前还没有创建界面
这是创建后的目录结构

#### 编写逻辑
打开index.vue,键入下面的组件源码:
```ts
```
上面的代码,我们自定义了一个 名为的UTS 组件,该组件对外提供了一个包含按钮的简单UI实现,并且对外暴露了一个名为 `buttonText`字符串属性,用来构建按钮上的文案
接下来,我们介绍在uni-app项目中如何使用它
#### 使用组件
> 注意:UTS组件默认全局注册,无需使用者手动配置
我们在uni-app项目中新建 helloView.nvue 页面,

直接使用`uts-hello-view`标签,并且定义`buttonText`文本内容即可看到效果。
点击按钮,可以在控制台看到组件内部实现的日志输出
```js
UTS view组件
```
#### 运行和测试
在当前示例中,不涉及第三方依赖,使用标准基座直接运行即可
## 包含第三方SDK的示例
本章节以lottie动画组件为例,介绍包含三方SDK的UTS组件开发过程
#### 创建插件
在HBuilder X 中选中Uni-App项目下 uni_modules目录
todo 目前还没有创建界面
这是创建后的目录结构

#### 引入依赖
打开 ~/uni_modules/uts-animation-view/utssdk/app-android/config.json
键入如下代码:
```
"dependencies": [
"com.airbnb.android:lottie:3.4.0"
]
```
UTS组件建议使用远程依赖的方式集成,如果需要以AAR的形式添加SDK,可以添加到
~/uni_modules/uts-animation-view/utssdk/app-android/libs目录
依赖的配置原则与UTS插件一致 [UTS插件依赖说明](https://uniapp.dcloud.net.cn/plugin/uts-for-android.html#_3-4-%E5%A2%9E%E5%8A%A0libs%E4%BE%9D%E8%B5%96%E8%B5%84%E6%BA%90)
#### 编写逻辑
打开index.vue,键入下面的组件源码:
```ts
```
上面的代码我们实现了一个支持lottie动画播放的 UTS组件,标签名称为 `uts-animation-view`
对外提供了下列属性和方法
|属性 |类型 |默认值 |描述 |
|:--- |:-- |:-- |:--- |
|`path` |string ||`lottie`资源路径,支持本地地址和`http`协议下的网络地址|
|`loop` |boolean|false |动画是否循环播放|
|`autoplay` |boolean|true |动画是否自动播放|
|`action` |string |play |动画操作,可取值 play、pause、stop|
|`hidden` |boolean|true |是否隐藏动画|
|`bindended`|event | |当播放到末尾时触发 ended 事件|
|`setRepeatMode`|function| |设置动画的重复方式,RESTART:重新开始播放,REVERSE,反向播放|
#### 使用`uts-animation-vie`组件
在uni-app项目中新建 lottie/index.nvue 页面

引用自定义 uts-animation-view 组件,并编写测试用例
```
```
以上,我们完成了 `uts-animation-view`组件的集成和使用工作
#### 运行和测试
在当前例子中,因为配置了额外的第三方依赖,需要自定义基座方能使用
## 快速体验
开发者可以使用[Hello UTS](https://gitcode.net/dcloud/hello-uts) 快速体验UTS 组件开发
Lottie动画示例,对应的源码实现:~/uni_modules/uts-animation-view
`uts-animation-view`动画示例,对应的源码实现:~/uni_modules/uts-animation-view
## 常见问题