Decorator

复制代码
// 要使用装饰器,需要在tsconfig.json中开启 "experimentalDecorators": true, "emitDecoratorMetadata": true
// 装饰器就是给对应的类、属性、参数、方法添加前置的功能

import axios from "axios";

// 类装饰器 ClassDecorator
// 定义类装饰器,装饰器命名习惯是大写字母开头
// const Base:ClassDecorator = (target) => {
//   console.log(target); // 输出的是http类的构造函数
//   // 给类加装饰,对http添加属性和方法
//   target.prototype.name = 'bai'
//   target.prototype.fn = () => {
//     console.log('fn');
//   }
// }
// // 使用方式是在class上一行, @类装饰器名
//  @Base
//  class http {}
//  const h = new http() as any
//  h.fn() // fn
//  console.log(h.name); // bai

import 'reflect-metadata'
 // 装饰工厂,因为不能直接给dec传参,使用函数柯里化传入参数
 const Base = (name:string) => {
  const dec:ClassDecorator = (target) => {
    // 给类加装饰,对http添加属性和方法
    target.prototype.name = name
    target.prototype.fn = () => {
      console.log('fn');
    }
  }
  return dec
}
// 方法装饰器
const Get = (url:string) => {
  // 方法装饰器MethodDecorator,描述的类型是PropertyDescriptor
  const fnDec:MethodDecorator = (target,key,descriptor:PropertyDescriptor) => {
    // target是{},key是方法名getList,descriptor是获取方法的描述,descriptor.value获取函数
    console.log(target,key,descriptor);
    // 相当于把getList要做逻辑都写这里了,然后通过descriptor.value把请求返回的结果传给getList
    axios.get(url).then(res => {
      descriptor.value(res.data)
    })
  }
  return fnDec
}
const Post = (url:string) => {
  // 方法装饰器MethodDecorator,描述的类型是PropertyDescriptor
  const fnDec:MethodDecorator = (target,key,descriptor:PropertyDescriptor) => {
    // target是{},key是方法名getList,descriptor是获取方法的描述,descriptor.value获取函数
    console.log(target,key,descriptor);
    // 通过Result参数修饰器的定义的key,获取value=result
    const key1 = Reflect.getMetadata('key',target)
    axios.get(url).then(res => {
      // 直接取res.data.result值
      descriptor.value(key ? res.data[key1]:res.data)
    })
  }
  return fnDec
}
// 参数修饰器
const Result = () => {
  const fn:ParameterDecorator = (target,key,index) => {
    // 使用reflect-metadata的语法
    // 第一个参数是自定义的,传递给方法装饰器接收
    // 第二个参数是指定要对data里的属性名,相当于value,
    // 第三个是自己
    Reflect.defineMetadata('key','result',target)
  }
  return fn
}
// 属性装饰器,意义不大,是获取属性名
const nameDeco:PropertyDecorator = (target,key) => {
  // key是name
  console.log(target,key)
}
// 使用装饰器的时候传入参数
 @Base('bai')
 class http {
  @nameDeco
  name: string
  constructor(name:string){
    this.name = name
  }
  @Get('https://api.apiopen.top/api/getHaoKanVideo?page=0&size=10')
  getList(data:any) {
    console.log(data);
  }
  @Post('https://api.apiopen.top/api/getHaoKanVideo?page=0&size=10')
  postList(data:any) {

  }
 }
 const h = new http('123') as any
 h.fn() // fn
 console.log(h.name); // bai
 
复制代码

 

posted on   ChoZ  阅读(3)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示