diff --git a/docs/plugin/_sidebar.md b/docs/plugin/_sidebar.md index e738b6991c3d13dc53a02320bb3431459bd6d8ee..2fe9ea46b8dab3b689d73b0ba5f74b1c9cbc7b5a 100644 --- a/docs/plugin/_sidebar.md +++ b/docs/plugin/_sidebar.md @@ -2,8 +2,11 @@ * [插件市场介绍](https://uniapp.dcloud.net.cn/plugin/plugin-ext-introduction.html) * [uni_modules](https://uniapp.dcloud.net.cn/plugin/uni_modules.html) * uts插件 - * [uts插件开发入门](uts-plugin.md) - * [uts页面组件开发入门](uts-component.md) + * [uts插件开发](uts-plugin.md) + * uts页面组件开发 + * [概述](uts-component.md) + * [标准模式组件开发](uts-component-vue.md) + * [uni-app兼容模式组件开发](uts-component-compatible.md) * [uts原生混编](uts-plugin-hybrid.md) * [uts中使用uni api](uts-uni-api.md) * [Android平台uts开发指南](uts-for-android.md) diff --git a/docs/plugin/uts-component-compatible.md b/docs/plugin/uts-component-compatible.md new file mode 100644 index 0000000000000000000000000000000000000000..47cb4fab58a97af54a988b815d2083f93ce16d40 --- /dev/null +++ b/docs/plugin/uts-component-compatible.md @@ -0,0 +1,1954 @@ +# uts插件 - uni-app兼容模式组件(原“组件插件”)开发 + +> HBuilderX3.6.18 及以上版本支持 + +本文重点在于讲述如何在app-android和app-ios上,将一个原生UI封装为兼容uni-app项目的UTS组件,供使用者在nvue/uvue页面template中以组件的方式调用。 + +## 前置条件 + +继续阅读文档前,开发者需要了解以下前置条件: + +- 了解 `标准模式` 和 `uni-app兼容模式` 的差异,详情参考[uts插件开发概述](./uts-component.md) +- 了解 [uts语法](/uts/) 和 [uts原生插件](uts-plugin.md) +- 了解 [Vue组件](https://uniapp.dcloud.net.cn/tutorial/vue3-components.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.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暂未支持。 + +::: preview + +> Android + +```html + + + + + + + +``` + +> iOS + +```html + + + + +``` + +::: + +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载体正在被创建实现|开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型|必须实现| +|NVLoaded |组件view载体创建完成|需要在对应的原生view创建完成后执行的逻辑|可选| +|NVLayouted |组件对应平台的view载体已布局结束 |需要在view布局结束后执行的逻辑 |可选| +|NVBeforeUnload |view载体即将被卸载 |View卸载前,需要回收资源的逻辑 |可选| +|NVUnloaded |view载体已经被卸载 |View卸载后,需要回收资源的逻辑 |可选| +|unmounted |组件在内存被销毁 |资源回收逻辑 |可选| + + +除上述生命周期外,还存在下列可选周期函数: + ++ NVMeasure + +NVMeasure 用于告诉排版系统,组件自身需要的宽高,具体的调用时机由排版系统决定。 + +一般情况下,组件的宽高应该是由终端系统的排版引擎决定,组件开发者不需要实现此函数。 + +但是部分场景下,组件开发者需要自己维护宽高,则需要开发者重写此函数 + + +注意: + + + 只有非容器组件生效,容器组件不应该重写此函数 + + + HBuilder X 4.25 版本后新增 `UTSMeasureMode` 类型入参,包含组件宽高在css中的设定: 0 代表未指定css中的宽高属性 / 1 代表已指定css中的宽高属性 + + ++ NVUpdateStyles + +需要HBuilder X 3.96版本 + +NVUpdateStyles 用来监听组件的外部style 变化,通常用来写响应外部的css样式变化从而动态更新组件内部状态场景 + +我们可以在组件内部这样实现: + +```uts +NVUpdateStyles(styles: Map){ + console.log("NVUpdateStyles",styles) +} +``` + ++ NVRecycler + +HBuilderX 4.0版本起支持,仅uni-app x App-Android平台支持 + +当UTS组件在`list-view`组件中使用时,由于[复用机制](../component/list-view.md),UTS组件可能表现异常(UI、事件回调等),因此,组件开发者需要在此函数中进行相应的逻辑处理。 + +比如我们使用UTS组件封装了一个Android原生的`EditText`控件(输入框),代码如下 + +```html +NVLoad() : EditText { + let editText = new EditText($androidContext!); + return editText; +} +``` + +然后我们在`list-view`组件中使用该UTS组件,当我们在第一个输入框中随机输入几个字符后,开始滚动列表,会发现之前输入的字符又出现在下面某个`list-item`中,这就是一个典型的由于复用机制导致的UI状态异常问题。此时我们就需要在NVRecycler()函数中处理该问题,代码如下 + +```html +NVRecycler() { + // 发生复用时置空输入框内容 + this.$el?.setText("") +} +``` + +[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",Any)|函数 |发送已注册的事件 |全部平台 |$emit(事件名称-必选,事件参数可选)| + +**注意** + +`UTSAndroid.getUniActivity()/UTSAndroid.getAppContext()` 在组件内不建议使用,请使用`$androidContext`来替代 + + +### 通用事件 + +对于UTS组件来说,除了通过 $emit/emits 函数来自定义组件事件外,UTS组件还内置了下列通用事件: + + +|事件名称 |简介 +|:------- |:-------- +|click |组件点击事件响应 +|longpress |组件长按事件响应 + + +通用事件,组件的使用者无需实现,直接使用 + +```html + +``` + + + +## 简单View的示例 + +本章节以 一个极简的组件开发为例,介绍说明UTS组件开发流程 + +### 创建插件 + +在HBuilder X 中选中Uni-App项目下 uni_modules目录,右键选择新建`uni_modules插件` + +![创建界面](https://native-res.dcloud.net.cn/images/uts/component/image0.png) + + +这是创建后的目录结构 + +![目录结构](https://native-res.dcloud.net.cn/images/uts/component/image1.jpg) + + +### 编写逻辑 + +打开index.vue,键入下面的组件源码: + +::: preview + +> Android + +```html + + + + + + + +``` + +> iOS + +```html + + + + +``` + +::: + +上面的代码,我们自定义了一个 名为 "uts-hello-view" 的UTS 组件,该组件对外提供了一个包含按钮的简单UI实现,并且对外暴露了一个名为 `buttontext`字符串属性,用来构建按钮上的文案 + +接下来,我们介绍在uni-app项目中如何使用它 + +### 使用组件 + +> 注意:UTS组件默认全局注册,无需使用者手动配置 + +我们在uni-app项目中新建 helloView.nvue 页面, + +![](https://native-res.dcloud.net.cn/images/uts/component/helloview_use_file.jpg) + +直接使用`uts-hello-view`标签,并且定义`buttontext`文本内容即可看到效果。 + +点击组件内置按钮,可以在控制台看到组件内部实现的日志输出 + +点击`调用组件的方法`按钮,可以看到组件内置方法被调用 + + +```html + + + + + +``` + + +### 运行和测试 + +在当前示例中,不涉及第三方依赖,使用标准基座直接运行即可 + + + +## 包含第三方SDK的示例 + +本章节以lottie动画组件为例,介绍包含三方SDK的UTS组件开发过程 + +### 创建插件 + +在HBuilder X 中选中Uni-App项目下 uni_modules目录,右键选择新建`uni_modules插件` + +![创建界面](https://native-res.dcloud.net.cn/images/uts/component/image0.png) + + +这是创建后的目录结构 + +![目录结构](https://native-res.dcloud.net.cn/images/uts/component/image3.jpg) + + +### Android 平台引入依赖 + +打开 ~/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://doc.dcloud.net.cn/uni-app-x/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) + + +### iOS 平台引入依赖库 + +iOS 平台需要将三方依赖库放到 组件目录下 app-ios/Frameworks 中 + + +### 编写逻辑 + +打开index.vue,键入下面的组件源码: + +::: preview + +> Android + +```ts + + + + + + +``` + +> iOS + +```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-view`组件 + +在uni-app项目中新建 lottie/index.nvue 页面 + +![](https://native-res.dcloud.net.cn/images/uts/component/lottie_use_file.jpg) + +引用自定义 `uts-animation-view` 组件,并编写测试用例 + +``` + + + + +``` + +以上,我们完成了 `uts-animation-view`组件的集成和使用工作 + + +### 运行和测试 + +在当前例子中,因为配置了额外的第三方依赖,需要自定义基座方能使用 + + + +## UTS开发容器组件 + +### 简介 + +组件一般有两种场景,第一种是: 单标签组件 +```html + +``` + +我们上面介绍的 `uts-hello-view`或者`uts-animation-view`都是这种类型 + +第二种是 作为容器使用: + +```html + + 文字子组件 + + +``` +### 声明 + +UTS组件作为容器组件与普通View组件遵循完全相同的规范, + +唯一的区别在于 当组件布局中包含 `` 标签时,编译器会自动将其转换为容器组件 + +::: preview + +> Android + +```ts + + + + +``` + +> iOS + +```ts + + +``` + +::: + +如上,我们即可到了一个最简的UTS容器组件 + + +### 使用容器组件 + +UTS容器组件的使用与Vue等常见的前端容器组件一致。唯一要注意的是,目前UTS容器组件还不支持 具名插槽。 + +如下是一个容器组件的使用示例 + + +```js + + + + + +``` + +### 应用程序生命周期函数监听 + UTS 组件同样支持对应用程序生命周期函数的监听,方式和 UTS 插件中的完全一致。具体使用方法[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#hooksClass) + + + +## 快速体验 + +开发者可以使用[Hello UTS](https://gitcode.net/dcloud/hello-uts) 快速体验UTS 组件开发 + +Lottie动画示例,对应的源码实现:~/uni_modules/uts-animation-view + +`uts-animation-view`动画示例,对应的源码实现:~/uni_modules/uts-animation-view + + + +## 常见问题 + +### 使用者需要指定 组件宽高 + +``` + +``` + +如果不通过style 指定组件宽高,会导致组件不显示 + + +### UTS-Android 插件涉及的像素单位说明: rpx,逻辑像素px,物理像素px + +|单位|说明|使用场景| +|----|---|---| +|逻辑像素px |逻辑像素 对应到 android中的 dp| 组件使用者 在页面css中使用 举例:`width:480px` | +|物理像素px |真实的设备像素,与dp 直接的换算关系是 dp * 屏幕密度 = 物理像素 px| android 原生api 传入和返回的单位均为物理像素,比如 设置layoutParam 参数,获取View宽高等 | +|rpx |屏幕宽度固定750单位前提下的逻辑像素| 组件使用者 在页面css中使用 举例:`width:750rpx`,可以使用UTSAndroid.rpx2px() 函数进行rpx 和 逻辑像素 px的转换| + +为了让组件使用者的有更好的体验,UTS 插件 应该以 **逻辑像素 px** 作为标准的像素单位: + ++ 1 内置的UTS插件/组件,涉及对外交互时会自动进行单位转换,抹平相关差异。比如 `swiper`等组件监听滑动距离等场景 + ++ 2 建议 插件开发者的插件在设计对外像素单位时也进行单位的转换,以逻辑像素px 作为输出结果 + + + + + + diff --git a/docs/plugin/uts-component-vue.md b/docs/plugin/uts-component-vue.md new file mode 100644 index 0000000000000000000000000000000000000000..37ecf3338d93d0c352631a8f718a88a2570db0e9 --- /dev/null +++ b/docs/plugin/uts-component-vue.md @@ -0,0 +1,511 @@ +# uts插件 - 标准模式组件开发 + +> HBuilderX4.31 及以上版本支持 + +本文重点在于讲述如何在app-android和app-ios上,使用vue组件开发规范封装原生UI封装为 uni-app x 项目使用的UTS组件,供使用者在uvue页面template中以组件的方式调用。 +主要思路是将app平台的原生view关联内置 [native-view](../component/native-view.md) 组件,实现UTS组件的特定功能及UI展示。 + + + +## 前置条件 + +继续阅读文档前,开发者需要了解以下前置条件: + +- 了解 `标准模式` 和 `uni-app兼容模式` 的差异,详情参考[uts插件开发概述](./uts-component.md) +- 了解 [uts语法](/uts/) 和 [uts原生插件](uts-plugin.md) +- 了解 [vue组件](https://uniapp.dcloud.net.cn/tutorial/vue3-components.html) +- 了解 [native-view组件](../component/native-view.md) + + + +## UTS插件-标准模式组件目录结构 + +
+
+┌─components                      // vue组件代码
+|   ├─xxx                      // vue组件名称文件夹  xxx代替组件名称
+|       ├─xxx.uvue             // vue组件uts代码 xxx代替组件名称
+├─static                          // 静态资源
+├─utssdk
+│	├─app-android                 //Android平台目录
+│	│	├─assets                  //Android原生assets资源目录,可选
+│	│	├─libs                    //Android原生库目录,可选
+│	│	├─res                     //Android原生res资源目录,可选
+│	│	├─AndroidManifest.xml     //Android原生应用清单文件,可选
+│	│	├─config.json             //Android原生配置文件
+│	│	├─index.uts               //Android原生插件能力实现,可选
+│	├─app-ios                     //iOS平台目录
+│	│	├─Frameworks              //iOS原生依赖的第三方 framework 依赖库存放目录,可选
+│	│	├─Resources               //iOS原生所依赖的资源文件存放目录,可选
+│	│	├─info.plist              //iOS原生所需要添加到主 info.plist 文件中的配置文件,可选
+│	│	├─UTS.entitlements        //iOS原生所需要添加到主工程 .entitlements 文件中的配置文件,可选
+│	│	├─config.json             //iOS原生配置文件
+│	│	├─index.uts               //iOS原生插件能力实现,可选
+│	├─web                         //web平台目录
+│	│	└─index.uts
+│	└─index.uts                   // 跨平台插件能力实现,可选
+└─package.json                    // 插件清单文件
+
+
+ +如上所示,UTS插件-标准模式组件目录结构与UTS插件基本相同,差别在于components目录,vue组件代码存放components目录下。 + +其他目录文件详情可参考[UTS插件文档](https://doc.dcloud.net.cn/uni-app-x/plugin/uts-plugin.html#%E6%8F%92%E4%BB%B6%E7%9A%84%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84) + + + +## 开发UTS插件-标准模式组件 + +### 构建标准模式组件 + +HBuilder X 选中你的项目,项目根目录选中uni_modules目录,右键选择新建uni_modules插件,弹窗后分类选择 “UTS插件-标准模式组件”,填写组件名称,以下均已 native-button 为例 + +![](https://web-ext-storage.dcloud.net.cn/doc/uts/uts_plugin/create-uts-vue-component.png) + +创建完毕 HBuilder X 会自动构建模版文件,参考:`UTS插件-标准模式组件目录结构` + + +### 标准模式组件功能实现 + +#### 添加 native-view + +构建标准模式组件后,HBuilder X 会自动创建components/native-button/native-button.uvue文件,在该文件编写代码添加 native-view 标签 + +```html + +``` + +#### native-view 与 原生对象关联 + +native-view 初始化会触发 @init 事件,此时创建NativeButton对象,native-button.uvue代码中用NativeButton对象调用插件相关的API。将 UniNativeViewElement 传递给NativeButton对象,进行关联绑定 + +[NativeButton](#实现nativebutton对象)是在utssdk目录构建的原生对象。NativeButton对象内部处理原生view与native-view绑定关联业务 + +::: preview + +> 组合式 API + +```html + + +``` + +> 选项式 API + +```html + + +``` + +::: + +#### 组件声明方法 + +在 methods 节点中添加updateText方法,native-button组件使用者可调用该方法更新native-button文案。 [页面调用组件方法](https://doc.dcloud.net.cn/uni-app-x/vue/component.html#page-call-component-method) + +::: preview + +> 组合式 API + +```ts + +``` + +> 选项式 API + +```ts +methods: { + //对外函数 + updateText(value: string) { + this.button?.updateText(value) + } +} +``` + +::: + +#### 组件声明props + +native-button 声明props,例如native-button的文案信息text属性,按vue组件规范监听到text属性更新,通过NativeButton对象驱动更新原生view属性,在components/native-button/native-button.uvue编写如下代码,具体参考[vue组件Props规范](https://cn.vuejs.org/guide/typescript/composition-api#typing-component-props) + +::: preview + +> 组合式 API + +```html + +``` + +> 选项式 API + +```html + +``` + +::: + +#### 组件声明事件 + +native-button 声明事件,例如原生组件触发点击事件@buttonTap, NativeButton对象通过 UniNativeViewElement 的 dispatchEvent 函数触发native-view的 @customClick 自定义事件。native-button.uvue监听native-view的 @customClick 自定义事件实现emit触发声明事件,具体参考[vue组件事件规范](https://cn.vuejs.org/guide/typescript/composition-api#typing-component-emits) + +::: preview + +> 组合式 API + +```html + + +``` + +> 选项式 API + +```html + + +``` + +::: + +**注意:** + +目前自定义事件参数仅支持[UniNativeViewEvent](../component/native-view#uninativeviewevent) + +native-button/components/native-button/native-button.uvue 最终代码如下: + +::: preview + +> 组合式 API + +``` html + + +``` + +> 选项式 API + +```html + + +``` + +::: + +#### 实现NativeButton对象 + +utssdk目录实现不同平台的原生NativeButton对象,构造参数获取UniNativeViewElement对象与原生view绑定,封装原生view功能关联的API。 + +::: preview + +> Android + +```uts +import { Button } from "android.widget" + +export class NativeButton { + $element : UniNativeViewElement; + + constructor(element : UniNativeViewElement) { + //接收传递过来的UniNativeViewElement + this.$element = element; + this.bindView(); + } + + button : Button | null = null; + bindView() { + //通过UniElement.getAndroidActivity()获取android平台activity 用于创建view的上下文 + this.button = new Button(this.$element.getAndroidActivity()!); //构建原生view + //限制原生Button 文案描述不自动大写 + this.button?.setAllCaps(false) + //监听原生Button点击事件 + this.button?.setOnClickListener(_ => { + const detail = {} + //构建自定义UniNativeViewEvent返回对象 + const event = new UniNativeViewEvent("customClick", detail) + //触发原生Button的点击事件 + this.$element.dispatchEvent(event) + }) + //UniNativeViewEvent 绑定 安卓原生view + this.$element.bindAndroidView(this.button!); + } + + updateText(text: string) { + //更新原生Button 文案描述 + this.button?.setText(text) + } + + destroy(){ + //数据回收 + } +} +``` + +> iOS + +```uts +import { UIButton, UIControl } from "UIKit" + +export class NativeButton { + + element : UniNativeViewElement; + button : UIButton | null; + + constructor(element : UniNativeViewElement) { + // 接收组件传递过来的UniNativeViewElement + this.element = element; + super.init() + this.bindView(); + } + + // element 绑定原生view + bindView() { + // 初始化原生 UIButton + this.button = new UIButton(type=UIButton.ButtonType.system) + // 构建方法选择器 + const method = Selector("buttonClickAction") + // button 绑定点击回调方法 + button?.addTarget(this, action = method, for = UIControl.Event.touchUpInside) + // UniNativeViewElement 绑定原生 view + this.element.bindIOSView(this.button!); + } + + updateText(text : string) { + // 更新 button 显示文字 + this.button?.setTitle(text, for = UIControl.State.normal) + } + + /** + * 按钮点击回调方法 + * 在 swift 中,所有target-action (例如按钮的点击事件,NotificationCenter 的通知事件等)对应的 action 函数前面都要使用 @objc 进行标记。 + */ + @objc buttonClickAction() { + //构建自定义 UniNativeViewEvent 对象 + let event = new UniNativeViewEvent("customClick") + //触发自定义事件 + this.element.dispatchEvent(event) + } + + destroy() { + // 释放 UTS 实例对象,避免内存泄露 + UTSiOS.destroyInstance(this) + } +} +``` + +::: + +更多实现可参考 标准模式组件 [native-button](https://gitcode.net/dcloud/hello-uni-app-x/-/tree/dev/uni_modules/native-button) + +此时一个简单的UTS插件-标准模式组件就完成了, + +**注意:** ++ UTS插件-标准模式组件的 components 目录下的代码中不能含有原生平台任何引用对象,这会导致vue原生组件无法跨平台,与原生平台关联的代码都应放在UTS插件中 ++ ios平台需要vue组件主动释放 uts 实例,所以页面触发 unmounted 生命周期时需要调用 this.button?.destroy() 避免内存泄露 ++ android平台 native-view 组件不支持border、background、box-shadow属性,可以使用view标签包裹native-view,在view标签设置以上属性 + + +### 页面引用UTS插件-标准模式组件 + +以 native-button 为例, 创建标准模式组件的项目页面可以直接使用 native-button 标签,也可将native-button插件包放置其他项目的uni-modules文件夹中。项目页面即可使用 native-button 标签 + +```html + + + + + +``` \ No newline at end of file diff --git a/docs/plugin/uts-component.md b/docs/plugin/uts-component.md index 1dbd48581ac671d5a11dcee7ef9f93d6a9c7bd8d..cf921306eb85f8dffafb918c56fcfb6dcbe7431c 100644 --- a/docs/plugin/uts-component.md +++ b/docs/plugin/uts-component.md @@ -1,1994 +1,64 @@ -# UTS 组件开发 +# uts插件 - 组件开发 -> 需HBuilderX 3.6.18 及之后版本 +uts插件的组件开发,简称`uts组件`,是uts插件的一个分支。uts插件提供了原生API的扩展,而uts组件提供了原生UI组件的开发模式。 -> app平台目前支持nvue/uvue,暂不支持vue - -UTS组件,是UTS插件的一个分支。UTS插件提供了原生API的扩展,而UTS组件提供了原生UI组件的开发模式。 - -组件是一种独立,可复用的UI单元,用于单独封装和承担一定的代码逻辑。 +组件是一种独立、可复用的UI单元,用于单独封装和承担一定的代码逻辑。 组件与插件的区别在于:前者以标签的形式,对外提供UI封装;后者则只提供API,虽然API可能涉及UI,但仍然是API,无法以标签方式在页面模板中引用。 比如`