function logClass(params: any) { console.log(params); } @logClass class HttpClient{ constructor() { } getData() { } }
定义了一个 logClass 类 并且带了一个默认参数 params
这个 params == HttpClinent
function logClass(params: any) { console.log(params); params.prototype.httpUrl = "http.xxxxx"; // 通过原型链添加一个 给类添加一个属性 } @logClass class HttpClient{ constructor() { } getData() { } } var httpClient = new HttpClient(); console.log(httpClient.httpUrl);
运行结果:
通过 类装饰器添加 方法
function logClass(params: any) { console.log(params); params.prototype.httpUrl = "http.xxxxx"; // 通过原型链添加一个 给类添加一个属性 params.prototype.run = function() { console.log("run-app"); } } @logClass class HttpClient{ constructor() { } getData() { } } var httpClient = new HttpClient(); console.log(httpClient.httpUrl); httpClient.run(); // 执行通过装饰器添加的方法
function logClass(params: string) { console.log(params); // 传入的参数类型 return function(tarage:any) { // tarage == HttpClient } } @logClass("传入参数") class HttpClient{ constructor() { } getData() { } } var httpClient = new HttpClient();
如果是装饰器工厂必须要写入 参数 @logClass("传入参数")
可以根据装饰器传入的参数去实现需要的功能
function logClass(params: string) { console.log(params); // 传入的参数类型 return function(tarage:any) { // tarage == HttpClient tarage.prototype.apiUrl = params; // 通过原型链修改 类的属性 } } @logClass("http://xxxxxx123") class HttpClient{ constructor() { } getData() { } } var httpClient = new HttpClient();
而且还可以重载 构造函数
function logClass(target: any) { console.log(target); return class extends target{ apiUrl:any="修改后的数据"; getData() { this.apiUrl = this.apiUrl + "---===--"; console.log(this.apiUrl); } } } @logClass class HttpClient{ public apiUrl: string | undefined; constructor() { this.apiUrl = "我是构造函数里面的apiUrl"; } getData() { console.log(this.apiUrl); } } var httpClient = new HttpClient(); console.log(httpClient.apiUrl) httpClient.getData();
function logProperty(params: any) { console.log("接收传入的参数", params); return function(tarage: any, attr: any) { console.log("参数一:", tarage); // 对于实例化成员是类的原型对象 console.log("参数二:", attr);// 成员名字 } } class HttpClient{ @logProperty("test") public url:string|undefined; // 这个属性使用 属性装饰器 constructor() { } getData() { } }
通过参数一 修改属性值:
function logProperty(params: any) { console.log("接收传入的参数", params); return function(tarage: any, attr: any) { console.log("参数一:", tarage); // 对于实例化成员是类的原型对象 console.log("参数二:", attr);// 成员名字 tarage[attr] = params; // 这里修改属性值 } } class HttpClient{ @logProperty("test") public url:string|undefined; // 这个属性使用 属性装饰器 constructor() { } getData() { console.log( "url属性值", this.url); } } var httpClient = new HttpClient(); httpClient.getData(); // 输出 url属性值 test
function logMethod(params:any) { console.log("调用传入的参数", params) return function(tarage:any, methodName: string, desc:any){ console.log("参数一", tarage); // 实例成员是类的原型 console.log("参数二", methodName); // 成员名字, 方法名 console.log("参数三", desc); // 描述 } } class HttpClient{ public url:string|undefined; constructor() { } @logMethod("get") getData() { // 这个方法使用了 装饰器 console.log( "url属性值", this.url); } }
第一个参数是 实例成员的原型, 可以通过它给原型添加属性或方法
function logMethod(params:any) { console.log("调用传入的参数", params) return function(tarage:any, methodName: string, desc:any){ console.log("参数一", tarage); // 实例成员是类的原型 console.log("参数二", methodName); // 成员名字, 方法名 console.log("参数三", desc); // 描述 tarage.api = "我是装饰器添加的 属性"; tarage.run = function() { console.log("我是装饰器添加的方法"); } } } class HttpClient{ public url:string|undefined; constructor() { } @logMethod("get") getData() { // 这个方法使用了 装饰器 console.log( "url属性值", this.url); } } var httpClient = new HttpClient(); console.log(httpClient.api); // 输出: 我是装饰器添加的 属性 httpClient.run(); // 输出 我是装饰器添加的方法
第三个参数是 描述 修改装饰器方法, 把装饰器方法里面的所有参数修改为string类型
function logMethod(params:any) { console.log("调用传入的参数", params) return function(tarage:any, methodName: string, desc:any){ console.log(desc.value); // 输出 function() { console.log( "url属性值", this.url);} var methodFun = desc.value; desc.value = function(...args:any) { // 重写 getData 方法 args = args.map((value:any)=>{ return String(value); }); console.log(args); // 使用对象冒充, 还原之前的函数 methodFun.apply(this, args); // 执行输出 我是getData方法 } } } class HttpClient{ public url:string|undefined; constructor() { } @logMethod("get") getData(...args:any) { // 这个方法使用了 装饰器 console.log(args);// 输出: Array(2) ["123", "adb"] console.log( "我是getData方法"); } } var httpclient = new HttpClient(); httpclient.getData(123, "adb"); // 输出: Array(2) ["123", "adb"]
function logParams(params:any) { return function(target:any,methodName:any,paramsIndex:number){ console.log(params);// 我是装饰器参数 console.log(target); // Object {getData: , constructor: } console.log(methodName); // getData console.log(paramsIndex);// 0 } } class HttpClient{ public url:string|undefined; constructor() { } getData(@logParams("我是装饰器参数")uuid:any) { // 这个方法使用了 装饰器 console.log(uuid); console.log( "我是getData方法"); } } var httpClinet = new HttpClient(); httpClinet.getData("test");
注意装饰器的执行顺序:
属性装饰器>方法装饰器>方法参数装饰器>类装饰器
如果一个方法有两个装饰器, 那么 后面的装饰器先执行,再到前面的