// decorator.ts
// **各种装饰器执行顺序:属性装饰器 > 方法参数装饰器 > 方法装饰器 > 类装饰器; 如果每种有多个,则从后往前执行**
/**
* 1.类装饰器, 扩展原型的属性
*/
export function addAge(args: number) {
return function (target: Function) {
target.prototype.age = args
}
}
/**
* 2.属性装饰器, 修改原有属性的值
*/
export function Property(args: string) {
return function (target: any, attr: any) {
target[attr] = args
}
}
/**
* 3.1方法装饰器, 在class新增一个方法
*/
export function configurable(params: any) {
return (
target: any, //当前装饰的函数容器
propertyKey: string, //被装饰的函数
descriptor: PropertyDescriptor //描述属性
) => {
// console.log(target,'target')
// console.log(propertyKey,'propertyKey')
// console.log(descriptor.value,'descriptor')
// descriptor.configurable = params
target.run = () => {
console.log('run方法打印:', params)
}
}
}
/**
* 3.2方法装饰器, 修改原有方法
*/
export function parseFunc(params: any) {
return (
target: any, //当前装饰的函数容器
propertyKey: string, //被装饰的函数
descriptor: PropertyDescriptor //描述属性
) => {
const originalMethod = descriptor.value //保存当前方法
descriptor.value = function (...args: any[]) {
args = args.map(value => {
return String(value)
})
console.log(args, 'new args')
originalMethod.apply(this, args) //没有这句是直接修改, 有这句可以最后执行原来的内容
}
}
}
/**
* 4方法参数装饰器
*/
function Method(params: string) {
// 参数1 类的构造函数(静态成员)/原型对象(实例成员) prototype === HttpClient3.prototype
// 参数2 方法的名字
// 参数3 方法描述
return function (prototype: any, name: string, desc: any) {
// 保存之前的方法
const oldMethod = desc.value
desc.value = function (...args: any) {
args = args.map((item: any) => {
return String(item)
})
console.log('方法装饰器内部 ', args)
// console.log('method invoke start -----', new Date() - 0)
oldMethod.apply(this, args)
// console.log('method invoke end -----', new Date() - 0)
}
}
}
/**
* 省略里面函数的一种思路,暂未实现
*/
// export function parseFunc(target, name, descriptor) {
// const originalMethod = descriptor.value
// descriptor.value = function (...parseConf: any[]) {
// for (let index = 0; index < parseConf.length; index++) {
// const type = parseConf[index]
// console.log(type,'type')
// switch (type) {
// case 'number':
// parseConf[index] = Number(parseConf[index])
// break
// case 'string':
// parseConf[index] = String(parseConf[index])
// break
// case 'boolean':
// parseConf[index] = String(parseConf[index]) === 'true'
// break
// }
// return originalMethod.apply(this, parseConf)
// }
// }
// console.log(descriptor,'descriptor')
// return descriptor
// }
import * as Dor from './decorator'
// @Dor.addAge(17) //调用类装饰器,不能放到class里面
export default class Example {
[x: string]: any //表示 可能被装饰器新增的方法或者属性
age: number
@Dor.Property('百度') //更改属性apiurl的值
public apiurl: string | undefined
// constructor() {
// this.apiurl = '我是构造函数里面的apiUrl' //构造函数的值会覆盖属性装饰器里面的
// }
// @Dor.configurable('ddddddddddddddd') //调用方法装饰器 3.1
@Dor.parseFunc('99999') //调用方法装饰器 3.2 // 99999这个传参用到则传,不用可以不传
getData(params: any){
console.log('我是原来方法的内容')
}
}