随着 uni-app 对鸿蒙系统的支持不断增强,开发者可以通过 UTS 插件 实现鸿蒙原生组件的嵌入与交互。从 HBuilderX 4.62 版本开始,uni-app 提供了对鸿蒙原生组件的同层渲染支持,开发者可以直接在 .ets
文件中定义原生组件,并通过 UTS 插件将其集成到 uni-app 项目中。
本文将以「自定义按钮组件」为例,详细讲解如何在鸿蒙系统中注册原生组件,并在 uni-app 中调用它。
开发步骤详解
1. 创建 UTS 插件结构
目录结构
uni_modules/
└── wq-button-component/ ← 插件主目录
├── package.json ← 插件配置文件
├── utssdk/
│ ├── interface.uts ← 接口定义
│ └── app-harmony/
│ └── index.uts ← 鸿蒙实现(ETS 文件)
└── pages/
└── demo.vue ← 演示页面
配置 package.json
{
"uni_modules": {
"uni-ext-api": {
"uni": {
"customButton": {
"name": "customButton",
"app": {
"js": false,
"arkts": true
}
}
}
}
}
}
2. 在 ETS 文件中注册原生组件
ETS 实现代码
// uni_modules/wq-button-component/utssdk/app-harmony/index.ets
import { NativeEmbedBuilderOptions, defineNativeEmbed } from "@dcloudio/uni-app-runtime";
// 定义按钮组件的 BuilderOptions
interface ButtonBuilderOptions extends NativeEmbedBuilderOptions {
label: string;
}
// 定义点击事件的详细信息
interface ButtonClickEventDetail {
text: string;
}
// 原生按钮组件
@Component
struct ButtonComponent {
@Prop label: string;
onButtonClick?: Function;
build() {
Button(this.label)
.width('100%')
.height('100%')
.onClick(() => {
if (this.onButtonClick) {
const detail: ButtonClickEventDetail = {
text: 'test'
};
this.onButtonClick({ detail });
}
});
}
}
// 构造函数,将参数传递给组件
@Builder
function ButtonBuilder(options: ButtonBuilderOptions) {
ButtonComponent({
label: options.label,
onButtonClick: options?.on?.get('click')
})
.width(options.width)
.height(options.height);
}
// 注册原生组件,标签名为 'button'
defineNativeEmbed('button', {
builder: ButtonBuilder
});
3. 在 uni-app 页面中调用组件
模板代码
<template>
<view class="content">
<embed
class="native-button"
tag="button"
:options="options"
@click="handleClick"
></embed>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
options: {
label: '点击我',
width: 200,
height: 50
}
};
},
methods: {
handleClick(e) {
console.log('按钮被点击,事件内容:', e.detail.text);
this.options = {
label: '已点击',
width: 200,
height: 50
};
}
}
};
</script>
<style scoped>
.content {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.native-button {
width: 200px;
height: 50px;
margin: 10px auto;
}
</style>
关键点解析
1. 原生组件注册流程
- 使用
defineNativeEmbed
注册组件,指定标签名tag
和构建函数builder
。 builder
函数接收参数并返回鸿蒙原生组件实例。- 通过
@Component
和@Builder
装饰器定义组件结构和逻辑。
2. 事件传递机制
- 原生组件的事件通过
on
属性注册,例如onButtonClick
。 - 在
uni-app
页面中通过@click
监听事件,并接收事件对象e.detail.text
。
3. 动态属性更新
- 修改
options
对象的值(如label
)会触发组件更新。 - 需要确保
options
是响应式数据(如 Vue 的data
)。
运行与调试
1. HBuilderX 配置
- 安装 HBuilderX 4.62+。
- 在菜单栏选择 运行 → 运行到手机或模拟器 → 运行到鸿蒙。
- 确保设备已开启 开发者选项 和 USB 调试。
2. DevEco Studio 验证
- 查看日志输出,确认组件是否成功加载。
- 检查按钮点击事件是否触发并更新标签文本。
注意事项
- ETS 文件限制
- 鸿蒙原生组件仅支持定义在
.ets
文件中。 - UTS 插件需通过
import
引入.ets
文件。
- 权限声明
在
config.json
中添加必要权限:
{
"plus": {
"distribute": {
"harmony": {
"requestPermissions": [
"ohos.permission.GET_BUNDLE_INFO"
]
}
}
}
}
- 上下文获取
getContext()
需确保在鸿蒙环境下可用。- 可封装兼容性处理逻辑,避免空指针异常。
扩展思考
1. 复用组件模式
通过 @Reusable
装饰器实现组件复用,优化性能:
@Reusable
@Component
struct ReusableButton {
// 组件逻辑
}
2. 多类型组件注册
注册多个原生组件时,可使用不同标签名区分:
defineNativeEmbed('custom-button', { builder: CustomButtonBuilder });
defineNativeEmbed('custom-input', { builder: InputBuilder });
总结
通过 UTS 插件和鸿蒙原生组件的结合,开发者可以在 uni-app 中高效地扩展鸿蒙平台的能力。本文以按钮组件为例,演示了从组件注册到页面调用的完整流程,帮助开发者快速掌握鸿蒙原生组件的嵌入技巧。