鸿蒙Next-方法装饰器以及防抖方法注解实现
以下是关于 鸿蒙Next(HarmonyOS NEXT)中 MethodDecorator
的详细介绍及使用指南,结合了多个技术来源的实践总结:
一、MethodDecorator 的概念与作用
MethodDecorator
是鸿蒙Next框架中用于装饰类方法的装饰器,属于 ArkUI 装饰器体系 的一部分。它允许开发者为类方法动态添加元数据或功能扩展,例如实现方法拦截、状态监听、日志记录等场景。通过装饰器,开发者能以声明式的方式增强代码的可维护性和复用性。
核心特点:
非侵入式增强:在不修改原方法逻辑的前提下,通过装饰器注入额外逻辑。
元数据绑定:可为方法添加配置信息(如参数校验规则、权限控制标记)。
与状态管理联动:常与
@State
、@Prop
等状态装饰器结合,实现数据变化响应。
二、MethodDecorator 的语法与使用示例
1. 基本语法
function MyMethodDecorator(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
// 装饰器逻辑:修改或增强原方法
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`方法 ${propertyKey} 被调用`);
return originalMethod.apply(this, args);
};
return descriptor;
}
class MyClass {
@MyMethodDecorator
myMethod() {
// 原方法逻辑
}
}
2. 常见使用场景
(1) 方法调用日志记录
function LogMethod() {
return function (target: any, methodName: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`调用方法:${methodName},参数:${JSON.stringify(args)}`);
return original.apply(this, args);
};
};
}
@Component
struct MyComponent {
@LogMethod()
handleClick() {
// 处理点击事件
}
}
(2) 状态监听与联动通过 @Watch
装饰器(内置的 MethodDecorator
)监听状态变量变化并触发方法:
@Component
struct MyComponent {
@State count: number = 0;
@Watch('count') // 监听 count 变化
onCountChanged(newValue: number, oldValue: number) {
console.log(`count 从 ${oldValue} 变为 ${newValue}`);
}
build() {
Button('增加').onClick(() => this.count++);
}
}
此例中,@Watch
装饰器会在 count
变化时自动调用 onCountChanged
方法。
(3) 点击事件防抖
//period间隔时间
@Debounce(2000)
clickMethod(){
}
function Debounce(period: number = 750): MethodDecorator {
return function (
target: object,
propertyKey: string,
descriptor: PropertyDescriptor
): PropertyDescriptor {
const originalMethod = descriptor.value
let timeId: number = 0
descriptor.value = function (...args: object[]): void {
if (timeId !== 0) {
clearTimeout(timeId)
}
timeId = setTimeout(() => {
originalMethod.apply(this, args)
timeId = 0
},
period
)
}
return descriptor
}
}
(4) 监听某个方法的耗时
function MonitorCostTime(): MethodDecorator {
return function (target: object,
propertyKey: string,
descriptor: PropertyDescriptor) {
const originMethod = descriptor.value
descriptor.value = function (...args: object[]) {
let startTime = systemDateTime.getTime()
const result = originMethod.apply(this, args); // 调用原始方法
const endTime = systemDateTime.getTime(); // 获取方法执行后的时间
hilog.error(hilog.LogLevel.ERROR, "monitorCostTime", `方法消耗的时间为:${endTime - startTime}s`)
return result;
}
return descriptor
}
}
(5) 权限控制
function CheckPermission(permission: string) {
return function (target: any, methodName: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
if (hasPermission(permission)) {
return original.apply(this, args);
} else {
console.error('无权限执行此操作');
}
};
};
}
class UserService {
@CheckPermission('admin')
deleteUser() {
// 删除用户逻辑
}
}
三、与 ArkUI 框架的深度集成
1. 生命周期方法装饰
鸿蒙Next的组件生命周期方法(如 aboutToAppear
、aboutToDisappear
)本质上是内置的 MethodDecorator
,开发者可通过自定义装饰器扩展生命周期行为:
function TrackLifecycle() {
return function (target: any, methodName: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`组件生命周期方法 ${methodName} 被触发`);
return original.apply(this, args);
};
};
}
@Component
struct MyComponent {
@TrackLifecycle()
aboutToAppear() {
// 组件初始化逻辑
}
}
2. 动画与交互增强
结合 animateTo
方法,可通过装饰器封装动画逻辑:
function FadeAnimation(duration: number) {
return function (target: any, methodName: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
animateTo({
duration: duration,
onFinish: () => original.apply(this, args)
}, () => {
this.opacity = 0;
});
};
};
}
@Component
struct AnimatedButton {
@State opacity: number = 1;
@FadeAnimation(300)
handleClick() {
// 点击后的业务逻辑
}
build() {
Button('点击').opacity(this.opacity).onClick(() => this.handleClick());
}
}
四、注意事项与最佳实践
装饰器执行顺序
多个装饰器按 从下到上 的顺序执行(装饰器工厂函数从外到内)。避免副作用
装饰器应保持无状态,避免修改全局变量或依赖外部环境。性能优化
高频调用的方法慎用复杂装饰器逻辑,必要时通过缓存优化。兼容性
确保装饰器与鸿蒙Next的 API 版本兼容,避免使用实验性特性。
五、扩展应用:自定义高级装饰器
1. 异步方法拦截
function Retry(maxAttempts: number) {
return function (target: any, methodName: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = async function (...args: any[]) {
let attempts = 0;
while (attempts < maxAttempts) {
try {
return await original.apply(this, args);
} catch (error) {
attempts++;
console.log(`重试第 ${attempts} 次`);
}
}
throw new Error('操作失败');
};
};
}
class ApiService {
@Retry(3)
async fetchData() {
// 网络请求逻辑
}
}
2. 参数校验
function ValidateParams(...validators: Function[]) {
return function (target: any, methodName: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
validators.forEach((validator, index) => {
if (!validator(args[index])) {
throw new Error(`参数 ${index} 校验失败`);
}
});
return original.apply(this, args);
};
};
}
class Calculator {
@ValidateParams(
(x: number) => !isNaN(x),
(y: number) => y !== 0
)
divide(x: number, y: number) {
return x / y;
}
}
总结
MethodDecorator
是鸿蒙Next开发中实现 代码复用 和 逻辑解耦 的重要工具。通过合理使用内置装饰器(如 @Watch
)和自定义装饰器,开发者可以显著提升代码的可维护性,同时实现复杂的业务逻辑与交互效果。实际开发中需结合具体场景选择装饰器策略,并注意性能与兼容性问题。
关注我获取更多知识或者投稿