鸿蒙Next-方法装饰器以及防抖方法注解实现

news/2025/2/26 23:45:11

以下是关于 鸿蒙Next(HarmonyOS NEXT)中 MethodDecorator 的详细介绍及使用指南,结合了多个技术来源的实践总结:


一、MethodDecorator 的概念与作用

MethodDecorator 是鸿蒙Next框架中用于装饰类方法的装饰器,属于 ArkUI 装饰器体系 的一部分。它允许开发者为类方法动态添加元数据或功能扩展,例如实现方法拦截、状态监听、日志记录等场景。通过装饰器,开发者能以声明式的方式增强代码的可维护性和复用性。

核心特点:
  1. 非侵入式增强:在不修改原方法逻辑的前提下,通过装饰器注入额外逻辑。

  2. 元数据绑定:可为方法添加配置信息(如参数校验规则、权限控制标记)。

  3. 与状态管理联动:常与 @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的组件生命周期方法(如 aboutToAppearaboutToDisappear)本质上是内置的 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());
  }
}

四、注意事项与最佳实践

  1. 装饰器执行顺序
    多个装饰器按 从下到上 的顺序执行(装饰器工厂函数从外到内)。

  2. 避免副作用
    装饰器应保持无状态,避免修改全局变量或依赖外部环境。

  3. 性能优化
    高频调用的方法慎用复杂装饰器逻辑,必要时通过缓存优化。

  4. 兼容性
    确保装饰器与鸿蒙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)和自定义装饰器,开发者可以显著提升代码的可维护性,同时实现复杂的业务逻辑与交互效果。实际开发中需结合具体场景选择装饰器策略,并注意性能与兼容性问题。

关注我获取更多知识或者投稿

d625635cc096aea7ecdeace5281677e2.jpeg

335e9bf34e8e735ab06ed9e857cd1c51.jpeg


http://www.niftyadmin.cn/n/5869280.html

相关文章

六、 Spring Framework基础:MyBatis基本用法与实践

深入解析 Spring Data MyBatis&#xff1a;基本用法与实践 MyBatis 是一个流行的 Java 持久层框架&#xff0c;它通过 SQL 映射和动态 SQL 提供了灵活的数据库操作能力。在 Spring Boot 项目中&#xff0c;MyBatis 可以与 Spring Data 无缝集成&#xff0c;从而实现高效的数据…

本地大模型编程实战(22)用langchain实现基于SQL数据构建问答系统(1)

使 LLM(大语言模型) 系统能够查询结构化数据与非结构化文本数据在性质上可能不同。后者通常生成可在向量数据库中搜索的文本&#xff0c;而结构化数据的方法通常是让 LLM 编写和执行 DSL&#xff08;例如 SQL&#xff09;中的查询。 我们将演练在使用基于 langchain 链 &#x…

C++ 正则表达式分组捕获入门指南

在 C 中&#xff0c;正则表达式&#xff08;regex&#xff09;是一种用于匹配字符串模式的强大工具。正则表达式不仅能帮助你查找符合特定模式的字符&#xff0c;还能捕获匹配的子字符串&#xff08;即分组捕获&#xff09;。这篇文章将介绍 C 正则表达式中的分组捕获机制&…

一文2500字从0到1实现压测自动化!

大家好&#xff0c;我是小码哥&#xff0c;最近工作有点忙&#xff0c;一直在实现压测自动化的功能&#xff0c;今天来分享一下实现思路 我所在的业务线现在项目比较少了&#xff0c;所以最近一个月我都没有做业务测试&#xff0c;需求开发完后RD直接走免测就上线&#xff0c;…

腾讯SQL面试题变体实现:最长连续天数与允许1天中断的进阶解法

腾讯SQL面试题变体实现:最长连续天数与允许1天中断的进阶解法 作者:某七年数据开发工程师 | 2025年02月23日 关键词:滑动窗口、容错机制、连续区间优化 一、变体题型需求分析 在原题如何找出连续5天涨幅超过5%的股票基础上,需实现两个扩展场景: 最长连续天数:输出每只股…

物联网智能终端-低成本方案(HC32L196+EC800G+BLE+2.8寸串口屏)

背景介绍 公司前几年搞了一些基于Linux系统的网关和智能终端的开发工作&#xff0c;产品已经量产&#xff0c;投放市场后发现有几个问题&#xff0c;第一个问题是成本&#xff0c;能跑Linux系统的处理器成本都比较高&#xff0c;当然了它的性能也是比较强。第二个问题是功耗&am…

【Java项目】基于Spring Boot的旧物置换系统

【Java项目】基于Spring Boot的旧物置换系统 技术简介&#xff1a;采用Java技术、Spring Boot框架、MySQL数据库等实现。 系统简介&#xff1a;旧物置换系统包括管理员、用户、卖家。其主要功能包括管理员&#xff1a;首页、个人中心、用户管理、卖家管理、旧物类型管理、旧物信…

2 Text2SQL 智能报表方案介绍

0 背景 Text2SQL智能报表方案旨在通过自然语言处理&#xff08;NLP&#xff09;技术&#xff0c;使用户能够以自然语言的形式提出问题&#xff0c;并自动生成相应的SQL查询&#xff0c;从而获取所需的数据报表&#xff0c;用户可根据得到结果展示分析从而为结论提供支撑&#…