ArkTS 发展自 TS 语言,其装饰器与 TS 是一致的。主要包括:

1 类装饰器

2 属性装饰器

3 方法装饰器

4 方法参数装饰器

接下来我们主要讲述一下前三个装饰器的参数含义,以及应用范围。

关键类解析-Function

我们在了解装饰器之前首先了解一下这个 Function 的类的结构,因为这个类频繁的出现在装饰器相关的结构里,我们是需要知道一下的:

四大注解

装饰器

写法案例

调用时机

限制

类装饰器

ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;

是一个函数,这个函数返回的是一个 函数。。。

target: 是一个描述函数的对象,这个对象是一个 Function。 但是!这个里面有个 ProtoType 属性,就是这个类对应的原型!

原则上只要拿到这个原型就顺手可以做什么事情了。

但你不能对属性做什么,因为这特么都没有对象!

export function MyClassDecorator() : ClassDecorator{
  return (target: Function) => {
    hilog.info(DOMAIN, TAG, `MyClassDecorator target=${target.name}`)
    const propType: object = target.prototype as object
    const oldMethod = propType['onCreate']
    propType['onCreate'] = function (this: any, ...args: any[]) {
      hilog.info(DOMAIN, TAG, `MyClassDecorator() decorated target=${JSON.stringify(this)} args=${JSON.stringify(args)}`)
      oldMethod && oldMethod.apply(this, args)
    }
  };
}

类加载的时候被调用

全局只有一次被调用

不能用在 struct 上, struct 本质上不是类,组件的本质是全局函数,状态变量也是会被搞成代理,这他妈都不是类!

不能在 Sendable 修饰的类上用

能在 Ability 上用但是不建议

能在普通的是类的地方用

属性装饰器

PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;

target: 属性所在类的原型本身!就是原型类!这个里面你可以做太多东西了简直

propertyKey: 你自己属性在这个类中的名字

import { hilog } from "@kit.PerformanceAnalysisKit";

const TAG = "MyPropertyDecorator";
const DOMAIN = 0x0000;

export function MyPropertyDecorator() : PropertyDecorator {
  return (target, propertyKey) : void =>{
    console.log(`MyPropertyDecorator target=${target} propertyKey=${String(propertyKey)}`);
    const targetObject = target as object
    const onCerateFunc = targetObject['onCreate'] as Function
    const onAboutToAppearFunc = targetObject['aboutToAppear'] as Function

    targetObject['onCreate'] = function (this: any, ...args: any[]) {
      hilog.info(DOMAIN, TAG, `MyPropertyDecorator() onCreate 方法执行,当前属性为:${String(propertyKey)}`)
      onCerateFunc && onCerateFunc.apply(this, args)
    }

    targetObject['aboutToAppear'] = function (this: any, ...args: any[]) {
      hilog.info(DOMAIN, TAG, `MyPropertyDecorator() aboutToAppear 方法执行,当前属性为:${String(propertyKey)}`)
      onAboutToAppearFunc && onAboutToAppearFunc.apply(this, args)
    }
  }
}

类加载解析 class 的时候

方法装饰器

MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;

类加载解析 class 的时候

参数装饰器

ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;

类加载解析 class 的时候

类注解,属性注解,方法注解的使用范围

装饰范围

类装饰器

属性装饰器

方法装饰器

方法参数装饰器

组件 struct

❌ struct 的本质根本不是类,你写了不回调

语法不支持

-

-

普通类

可以在这个里面替换方法,就是将原型方法切换成你自己写的,然后在后续接上用户自己写的逻辑。

比如我给 EntryAbility 搞了一个

-

-

组件中的普通属性

-

target 是一个 ViewPU对象原型类!这个对象里面是有 aboutToAppeare 等等这类的函数入口的,其实也可以拿来用。

-

类中的普通属性

-

此时的 Target 本身就是一个原型类,直接拿来做更换即可

-

组件中的静态属性

-

target 是一个 Function 对象,这个对象的protoType 对象是ViewPU对象原型类, 这个对象里面是有 aboutToAppeare 等等这类的函数入口的,其实也可以拿来用。

-

类中的静态属性

-

此时的Target是一个 Function 对象

类的原型可以访问 Function 的 protoType 元素拿到!可以通过这种方式操作

-

类外面的 const 属性

-

❌ 编译报错, 不能用。

-

组件中的方法

-

target 是 ViewPU 的原型类

普通类中的方法

-

target 是你方法所属类的原型本身

普通类中的静态方法

-

target 是一个 Function,Function 里面的 property 是你方法所属类的原型本身

组件中的静态方法

target 是一个 Function, Function 里面的 property 是一个 ViewPU 的原型,里面有各种生命周期

全局方法

-

❌ 编译出错

构造方法

-

❌ 编译出错 构造方法不能被注解

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐