在typescript 中装饰器定义
装饰器(Decorators)为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式
- 装饰器 是一种特殊的生命 它能够附加类声明,方法,可以修改类的行为
- 通俗的讲装饰器是一个方法 ,可以注入到类中,方法,属性参数上来扩展,方法,属性的功能
- 常见的装饰器有 类装饰器 , 方法装饰器,参数装饰器
- 装饰器的写法 : 普通装饰器 (无法传参) , 装饰器工厂 ( 可以传参)
装饰器已是ES7的标准之一
一个普通装饰器(无法传递参数)
// 定义一个logclass装饰器
function logclass(pars: any) {
console.log(pars)
//pars当前类
//扩展属性
pars.prototype.apiurl = 'XXXXX'
//扩展方法
pars.prototype.run = function () {
console.log('我是run')
}
}
使用普通装饰器
@logclass
class httpclit {
constructor() { }
getData() {
//xxx
}
}
let s: any = new httpclit();
// 输出我们在装饰器定义的 在httpclit 原型的 apiurl 值
console.log(s.apiurl)
s.run() //调用装饰器扩张的新方法
类装饰器 装饰器工厂 (传递参数)
类装饰器表达式会运行当前函数被调用,类的构造函数作为其唯一的参数
如果装饰器返回一个值,他会使用提供函数来替换类的声明
//pars 是使用装饰器传递的参数
function factory(pars: string) {
//propt 是 httpclit 的原型
return (propt: any)=> {
console.log(pars)
console.log(params)
//像传递过来的原型添加方法
params.prototype.apiurl = pars;
}
}
//装饰器
@factory('http://www.zixia.top/api')
class httpclit {
getData() { }
}
let s: any = new httpclit();
console.log(s.apiurl) //调用 prototype 上面新添加的装饰器
接收多个参数 可使用 arguments (箭头函数没有arguments) 或者es6 的参数收集
function factory() {
return (params: any)=> {
console.log(arguments)
console.log(params)
}
}
@factory('http://www.zixia.top/api','zizizizi')
class httpclit {
getData() {
console.log('我是getData')
}
}
属性装饰器
属性装饰器表达式运行时当作函数被调用 传入2个参数:第一个为 类的原型对象 第二个为成员的名字
function logs(params:any) {
return function(tage:any){
console.log(params)
console.log('logslogs',tage)
tage.prototype.name = '我是定义在原型的属性'
}
}
function dub(params:any){
/**
* tager 为http原型
* attr 为装饰器传递过来的参数
*/
return function(tager:any,attr:any){
tager[attr]=params
}
}
// 类装饰器
@logs('XXXXXXXXXXXXXXXXXXXXXX')
class http{
//属性装饰器
@dub('www.baidu.api')
public url:any|undefined;
public quer:any|undefined;
// this.name 在类装饰器中调用赋值,此处ts会检测不通过,但是能正常执行下面代码
constructor(){
console.log('constructorconstructor',this.name)
}
getdada(){
console.log('getdada',this.url,this.name)
}
}
let g= new http()
g.getdada()
// 输出一下
[LOG]: "XXXXXXXXXXXXXXXXXXXXXX"
[LOG]: "logslogs", class http {
// this.name 在类装饰器中调用赋值,此处ts会检测不通过,但是能正常执行下面代码
constructor() {
console.log('constructorconstructor', this.name);
}
getdada() {
console.log('getdada', this.url, this.name);
}
}
[LOG]: "constructorconstructor", "我是定义在原型的属性"
[LOG]: "getdada", "www.baidu.api", "我是定义在原型的属性"
方法参数装饰器
参数装饰器表达式会在运行时当作函数被调用 可以使用参数装饰器为类的原型增加一些元素数据,传入一下3个参数:
对于静态成员来说是类的构造函数,对于实例的成员是类的原型对象
方法的名字
参数在函数参数列表中索引
function logData(...params: any) {
return function (prot: any, lastName: string, paramsIndex: number) {
console.log(params);
console.log(prot);
console.log(lastName);
console.log(paramsIndex);
// 向原型扩展方法
prot.lastName = params
}
}
class httpClient {
getDataLog(@logData('xxxx',123,456) uuid: string) {
console.log('方法', uuid);
}
}
let Client = new httpClient()
Client.getDataLog('uuidididiid')