Typescript中的装饰器
装饰器介绍
装饰器是一个方法,可以注入到类,方法,属性参数上来扩展类,属性,方法,参数的功能
常见装饰器:类装饰器,属性装饰器,方法装饰器,参数装饰器。
装饰器的写法:普通装饰器(无法传参),装饰器工厂(可传参)
类装饰器
可以是普通装饰器,无法传参
类装饰器在类声明之前被声明(紧靠着类声明)。类装饰器应用于类构造函数,可以用来监视、修改或替换类定义。
类装饰器可以在不修改类的前提下动态的扩展类的属性和功能
function beaty(parmas: any) {
console.log(parmas);
//parmas就是当前类
parmas.prototype.apiUrl = `动态扩展的属性`
parmas.prototype.run=function () {
console.log(`我是一个润方法`);
}
}
@beaty
class util {
constructor(){
}
getData() {
}
}
var i:any = new util()
console.log(i.apiUrl) //动态扩展的属性
i.run() //我是一个润方法
可以是装饰器工厂(可传参)
function beaty(parmas: string) {
return function(target:any) {
console.log(target);
// console.log(parmas);
target.prototype.apiUrlll = parmas
}
}
@beaty(`http://www.itying.com/api`)
class util {
constructor(){
}
getData() {
}
}
var i:any = new util()
console.log(i.apiUrlll)
类装饰器重载构造函数
(重载用在装饰方法中的constract方法中用extends关键字,然后重写类里面所有的方法和属性)
类装饰器表达式会在运行时当作函数被调用,类的构造 函数作为其唯一的参数
如果类装饰器返回一个值,他会使用提供的构造函数来替换类的声明
function beaty(target: any) {
console.log(target) //这个target是其装饰的util类
return class extends target {
//写一个类用extends关键字继承target,target就是类本身,重写里面的所有东西,并赋值
apiUrl: any = '我是修改之后的数据'
getData() {}
}
}
@beaty
class util {
public apiUrl: string | undefined
constructor() {
this.apiUrl = '我是构造函数的apiUrl'
}
getData() {
console.log(this.apiUrl)
}
}
let i = new util()
i.getData()
属性装饰器
属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:
1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。2、成员的名字
function beaty(params: any) {
//console.log(params) //这个target是其装饰的util类
return function (target:any,attr:any) {
console.log(target);
console.log(attr);
target[attr]=params
}
}
class util {
@beaty(`http`) //给url传东西
url: string | undefined
}
console.log(new util().url); //输出http
方法装饰器
它会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。
方法装饰会在运行时传入下列3个参数:
1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
2、成员的名字。
3、成员的属性描述符
function GET(url: string) {
return function (target:any, methodName: string, descriptor: PropertyDescriptor) {
console.log(target);
console.log(methodName);
console.log(descriptor);
target.apiUrl = 'ppppp'
target.run = function () {
console.log('run');
}
}
}
class Http {
constructor() { }
@GET("xx") //在方法上方定义
getUser() {
}
}
let i:any = new Http()
console.log(i.apiUrl); //输出ppppp
i.run() //输出run
方法参数装饰器
参数装饰器表达式会在运行时当作函数被调用,传入下列3个参数:
1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
2、参数的名字。
3、参数在函数参数列表中的索引。
function PathParam(paramName: string) {
return function (target:any, methodName: string, paramIndex: number) {
target.apiUrl = paramName;
}
}
class Http {
constructor() { }
getUser( @PathParam("userId11111") userId: string) {
console.log(userId);
}
}
var http:any = new Http()
http.getUser(123456)
console.log(http.apiUrl); //输出userId11111
装饰器执行顺序
属性>方法>方法参数>类
注:如果有多个同样的装饰器,它会先执行后面的装饰器。