普通装饰器 (无法传参)
// 类装饰器
function logClass(params:any) {
params.prototype.apiUrl = 'xxx'
params.prototype.run = function () {
console.log('i am run!')
}
}
@logClass
class HttpClient {
constructor() {}
getData() {}
}
var http:any = new HttpClient()
console.log(http.apiUrl)
http.run()
装饰器工厂 (可传参)
function logClass(params:string) { // params 是传递的参数
return function (target:any) { // target 是类的原型对象
target.prototype.apiUrl = params
}
}
@logClass('/api/demo')
class HttpClient {
constructor() {}
getData() {}
}
var http:any = new HttpClient()
console.log(http.apiUrl)
支持多个装饰器
// 如果有多个装饰器,会先执行后面的
@logClass1('aaa') // 后
@logClass2('bbb') // 先
class HttpClient {}
装饰器执行顺序
属性 >> 方法 >> 方法参数 >> 类
属性装饰器
function logProperty(params:string) {
return function (target:any, attr:any) {
// target 是类的原型对象, attr 属性的名称 (url)
target[attr] = params
}
}
@logClass('/api/demo')
class HttpClient {
@logProperty('http://www.baidu.com')
public url:any | undefined;
constructor() {}
getData() {
console.log(this.url)
}
}
var http:any = new HttpClient()
console.log(http.apiUrl)
构造函数重载
替换构造函数
function logClass (target:any) {
return class extends target {
apiUrl:any = '我是修改后的构造函数 apiUrl'
getData () {
console.log(this.apiUrl + ' - next')
}
}
}
@logClass
class HttpClient {
public apiUrl:string | undefined;
constructor() {
this.apiUrl = '我是构造函数 apiUrl'
}
getData() {
console.log(this.apiUrl)
}
}
var http = new HttpClient()
http.getData()
方法装饰器
如何替换/修改当前的方法
示例:将传入参数 强制修改为 String 类型
// 方法装饰器
function get() {
return function (target:any, methodName:any, desc:any) {
console.log(target) // 类的原型对象
console.log(methodName) // 方法名
console.log(desc) // 方法的属性Object
console.log(desc.value) // 方法值
// 将传入参数 强制修改为 String 类型
// -------------------------------------
var orginMethod = desc.value
desc.value = function (..args:any[]) {
args = args.map(value => {
return String(value)
})
// 修改(没有这句则是替换)
orginMethod.apply(this, args)
}
// -------------------------------------
}
}
class HttpClient {
public url:string | undefined;
constructor() {}
@get()
getData(..args:any[]) {
console.log(args)
// ['123', 'aaa']
}
}
var http:any = new HttpClient()
http.getData(123, 'aaa')
参数装饰器
比较少用
function logParams (params:any) {
return function (target:any, methodName:any, paramIndex) {
console.log(params) // abc
target.apiUrl = params
}
}
class HttpClient {
..
getData(@logParams('abcd') uuid:any) {
console.log('uuid:' + uuid)
}
}
var http:any = new HttpClient()
http.getData(123456)
console.log(http.apiUrl)
// uuid:123456
// abcd
欢迎技术指正与交流,转载请注明出处
https://www.imure.cn/2019/10/25/Typescript-Decorator/