掘金 后端 ( ) • 2024-04-02 10:44

视频教程

00_课程介绍_哔哩哔哩_bilibili

1. 什么是装饰器

装饰器是一种特殊类型的声明,可以被附加到类声明、方法、访问器、属性或参数上。装饰器使用 @expression 这样的语法,其中 expression 指向一个生成装饰器函数的表达式。装饰器函数会在运行时被调用,传入被装饰的声明作为参数,并有机会修改或增强其行为

1.1. 新建一个文件夹 descriptor

npm install typescript -g
npm install ts-node-dev -g
tsc --init

1.2. 在这个目录下新建index.ts

const bar = (num: number) => {
  console.log(num);
}

bar(10);
tsnd .\index.ts

1.3. 现在我们来体验装饰器

function decotators(target: any) {
  console.log('target', target);
}

@decotators
class Xt {

  constructor() {

  }

}

当我们在运行tsnd .\index.ts时,可以看到此时报错了,原因是装饰器还是实验性特性,要使用需要开启装饰器写法配置

我们需要把experimentalDecorators设置为true

我们再执行tsnd .\index.ts,就正常了

2. 类装饰器 主要是通过 @ 符号添加装饰器

@ 符号用于标记和调用装饰器函数的一种语法糖

他会自动把class的构造函数传入到装饰器的第一个参数 target,然后通过prototype可以自定义添加属性和方法

function decotator(target: any) {
  target.prototype.name = 'xt'
}

@decotator
class Xt {

  constructor() {

  }

}

const xt: any = new Xt()

console.log(xt.name)

3. 属性装饰器

同样使用@符号给属性添加装饰器,他会返回两个参数:

  • 1.原形对象
  • 2.属性的名称
const decotator: PropertyDecorator = (target: any, key: string | symbol) => {
  console.log(target, key)
}


class Xt {
  @decotator
  public name: string
  constructor() {
    this.name = ''
  }
  getName() {
    return this.name
  }
}

4. 参数装饰器

同样使用@符号给属性添加装饰器,他会返回两个参数:

  • 1.原形对象
  • 2.方法的名称
  • 3.参数的位置从0开始
const decotator: ParameterDecorator = (target: Object, key: string | symbol | undefined, index: number) => {
  console.log(target, key, index)
}


class Xt {
  public name: string
  constructor() {
      this.name = ''
  }
  getName(name:string,@decotator age:number) {
      return this.name
  }
}

5. 方法装饰器

同样使用@符号给属性添加装饰器,他会返回两个参数:

    1. 原形对象
    1. 方法的名称
    1. 属性描述符 可写对应writable,可枚举对应enumerable,可配置对应configurable
const decotator: MethodDecorator = (target: any, key: string | symbol, descriptor: any) => {
  console.log(target, key, descriptor)
}


class Xt {
  public name: string
  constructor() {
    this.name = ''
  }
  @decotator
  getName(name: string, age: number) {
    return this.name
  }
}

6. 自定义装饰器

const log: MethodDecorator = (target: any, key: string | symbol, descriptor: PropertyDescriptor) => {
    const originalMethod = descriptor.value;

    descriptor.value = function(...args: any[]) {
        console.log('先打印');
        return originalMethod.apply(this, args);
    };
};

class Xt {
    @log
    myMethod() {
        console.log('myMethod');
    }
}

const xt = new Xt();
xt.myMethod();
const log = (prefix: string): MethodDecorator => {
    return (target, key, descriptor: PropertyDescriptor) => {
      const originalMethod = descriptor.value;
      descriptor.value = function (...args: any[]) {
        console.log(`${prefix}先打印`);
        return originalMethod.apply(this, args);
      };
    };
};

class Xt {
  @log('11')
  myMethod() {
    console.log('2222');
  }
}

const xt = new Xt();
xt.myMethod();
import axios from 'axios'
 
const Get = (url: string): MethodDecorator => {
    return (target, key, descriptor: PropertyDescriptor) => {
        const originalMethod = descriptor.value;
        axios.get(url).then(res => {
            originalMethod(res, {
                status: 200,
            })
        }).catch(e => {
            originalMethod(e, {
                status: 500,
            })
        })
    }
}
 
class Xt {
    constructor() {
 
    }
    @Get('https://api.apiopen.top/api/getHaoKanVideo?page=0&size=10')
    getList (res: any, status: any) {
        console.log(res.data.result.list, status)
    }
  
}