装饰器:一种特殊类型声明,它能够被附加到类声明,方法,访问符,属性,参数上
定义一个类装饰器 他会把class Http的构造函数传入Base函数当作第一个参数 使用:@函数名
const Base: ClassDecorator = (target) => {
target.prototype.name = "新增的姓名";
target.prototype.fn = () => {
console.log("新增的方法");
};
};
@Base
class Http {}
const http = new Http() as any;
http.fn();
console.log(http.name);
属性装饰器 PropertyDecorator
参数装饰器 ParameterDecorator
方法装饰器 MethodDecorator
import axios from "axios";
import "reflect-metadata";
const Base = (name: string) => {
const fn: ClassDecorator = (target) => {
target.prototype.name = name;
target.prototype.fn = () => {
console.log("新增的方法");
};
};
return fn;
};
const Get = (url: string) => {
/**
*
* @param target
* @param key 方法名称getList
* @param descriptor {
"writable": true,
"enumerable": false,
"configurable": true,
value:f getList(data)
}
*/
const fn: MethodDecorator = (target, key, descriptor: PropertyDescriptor) => {
const keyWord = Reflect.getMetadata("keyWord", target);
const keyWordList = Reflect.getMetadata("keyWordList", target);
axios.get(url).then((res) => {
descriptor.value(
keyWord
? keyWordList
? res.data[keyWord][keyWordList]
: res.data[keyWord]
: res.data
);
});
};
return fn;
};
const Result = () => {
/**
*
* @param target
* @param key 方法名称getList
* @param index 参数位置 0
*/
const fn: ParameterDecorator = (target, key, index) => {
Reflect.defineMetadata("keyWord", "result", target);
};
return fn;
};
const List = () => {
const fn: ParameterDecorator = (target) => {
Reflect.defineMetadata("keyWordList", "list", target);
};
return fn;
};
@Base("zhangsan")
class Http {
@Get("https://api.apiopen.top/api/getHaoKanVideo?page=0&size=20") //方法装饰器
getList(@Result() @List() data: any) {
// console.log(data.result.list); //没加属性装饰器这样才能拿到list
console.log(data); //添加@Result()后就可以直接拿result 添加@Result()与@List()list
}
}
const http = new Http() as any;
装饰器工厂:使用函数柯里化实现
const Base = (name: string) => {
const fn: ClassDecorator = (target) => {
target.prototype.name = name;
target.prototype.fn = () => {
console.log("新增的方法");
};
};
return fn;
};
@Base("zhangsan")
class Http {}
const http = new Http() as any;
http.fn();
console.log(http.name);