ts的装饰器

console.log('装饰器.......')
// 装饰器就是一个方法,可以注入到类,方法,属性上来拓展类,属性,方法,参数的功能
// 常见:类装饰器,属性装饰器,方法装饰器,参数装饰器
// 写法:1.普通装饰器(无法传参) 2.装饰器工厂(可传参)

// 1.类装饰器
// 类装饰器在类声明之前被声明(紧靠着类声明)。 类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。
// 普通装饰器(无法传参)
function logClass(params: any) {
    console.log(params)
    // 通过原型链拓展类,属性,方法,参数
    params.prototype.apiUrl = 'xxx'
    params.prototype.run = function () {
        console.log('run...........')
    }
}

@logClass
class HttpClient {
    constructor() {}
    getData() {}
}
let http: any = new HttpClient()
console.log(http)
http.run()

// 装饰器工厂(可传参)
function logClass1(params: string) {
    return function (target: any) {
        console.log(params)
        console.log(target)
        target.prototype.apiUrl = params
    }
}

@logClass1('hello')
class HttpClient1 {
    constructor() {}
    getData() {}
}
let http1: any = new HttpClient1()
console.log(http1)

// 重载构造函数
function logClass2(target: any) {
    return class extends target {
        api: any = 'api2222'
        getData() {
            console.log(this.api + '333')
        }
    }
}

@logClass2
class HttpClient2 {
    public api: string | undefined
    constructor() {
        this.api = 'api11111'
    }
    getData() {
        console.log(this.api)
    }
}
let http2: any = new HttpClient2()
console.log(http2)
http2.getData()

// 2.属性装饰器
// 属性装饰器表达式会在运行时被当作函数调用
// 接收两个参数
// 1. 对于静态成员是类的构造函数,对于实例成员是类的原型对象
// 2. 成员的名字

// 类装饰器
function logClass3(params: string) {
    return function (target: any) {
        // console.log(params)
        // console.log(target)
        target.prototype.apiUrl = params
    }
}

// 属性装饰器
function logProperty(params: string) {
    return function (target: any, attr: any) {
        // console.log(params)
        // console.log(target)
        target[attr] = params
    }
}

@logClass3('hello33333')
class HttpClient3 {
    @logProperty('hello4444')
    public api: any | undefined
    constructor() {}
    getData() {}
}
let http3: any = new HttpClient3()
console.log(http3)

// 3.方法装饰器
// 应用在方法的属性描述上,可以用来监视、修改、替换方法定义
// 接收三个参数
// 1. 对于静态成员是类的构造函数,对于实例成员是类的原型对象
// 2. 成员的名字
// 3. 成员的属性的描述
function logClass4(params: string) {
    return function (target: any, methodsName: any, desc: any) {
        console.log(target)
        console.log(methodsName)
        console.log(desc)
        console.log(desc.value)
        let o = desc.value
        desc.value = function (...args: any[]) {
            args = args.map((item) => {
                return String(item) + params
            })
            o.apply(this, args)
        }
    }
}

class HttpClient4 {
    public api: any | undefined
    constructor() {}
    @logClass4('方法装饰器方法装饰器方法装饰器方法装饰器')
    getData(...args: any[]) {
        console.log(args)
        console.log('getDatagetDatagetData')
    }
}
let http4: any = new HttpClient4()
http4.getData(123, 'xxx')

// 4.参数装饰器
// 参数装饰器表达式会在运行时当作函数被调用,可以使参数装饰器为类的原型增加一些元素数据
// 1. 对于静态成员是类的构造函数,对于实例成员是类的原型对象
// 2. 参数的名字
// 3. 参数索引
function logClass5(params: string) {
    return function (target: any, methodsName: any, desc: any) {
        console.log(target)
        console.log(methodsName)
        console.log(desc)
    }
}

class HttpClient5 {
    public api: any | undefined
    constructor() {}

    getData(@logClass5('参数装饰器参数装饰器') uuid: any) {
        console.log(uuid)
    }
}
let http5: any = new HttpClient5()
http5.getData(1232123)

// 装饰器执行顺序
// 属性>方法参数>方法>>类
// 存在多个同样装饰器则是从下到上执行
function logClass6(params: string) {
    return function (target: any, methodsName: any, desc: any) {
        console.log(params)
    }
}
function logClass7(params: string) {
    return function (target: any, methodsName: any, desc: any) {
        console.log(params)
    }
}
function logClass8(params: string) {
    return function (target: any, methodsName: any, desc: any) {
        console.log(params)
    }
}
function logClass9(params: string) {
    return function (target: any, methodsName: any, desc: any) {
        console.log(params)
    }
}

function logClass10(params: string) {
    return function (target: any) {
        console.log(params)
    }
}

function logClass11(params: string) {
    return function (target: any, attr: any) {
        console.log(params)
    }
}

@logClass10('类装饰器装饰器')
class HttpClient6 {
    @logClass11('属性装饰器')
    public api: any | undefined
    constructor() {}
    @logClass8('方法装饰器装饰器1')
    @logClass9('方法装饰器装饰器2')
    getData(
        @logClass6('参数装饰器1') uuid1: any,
        @logClass7('参数装饰器2') uuid2: any
    ) {
        console.log(uuid1)
        console.log(uuid2)
    }
}
let http6: any = new HttpClient6()
http6.getData(1232123, 234)

 

posted on 2022-04-15 11:18  sss大辉  阅读(239)  评论(0编辑  收藏  举报

导航