Vue框架TypeScript装饰器使用指南小结

2020-06-14 05:58:09易采站长站整理

"output":"", // 方法输出的内容
"custom":"" // 自定义的日志内容
}

实现


export function Logger(logId?: string, hander?: Function) {
const loggerInfo =Object.seal({logId:logId, input:'',output:'', custom: ''});
const channelName = '__logger';
const msgChannel = postal.channel(channelName);
msgChannel.subscribe(logId, logData => {
// 根据业务逻辑来处理日志
console.log(logData);
});

return function (target: any,
key: string,
descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> {
const oldValue = descriptor.value
descriptor.value = function () {
const args: Array<any> = [];
for (let index in arguments) {
args.push(arguments[index]);
}
loggerInfo.input = `${key}(${args.join(',')})`;
// 执行原方法
const value = oldValue.apply(this, arguments);
loggerInfo.output = value;
hander && (loggerInfo.custom = hander(loggerInfo.input, loggerInfo.output) || '');
// 被调用时,会自动发出一个事件
msgChannel.publish(logId, loggerInfo);
}
return descriptor
}
}

使用


@Logger('event_get_detial1')
getDetial(id?: string, category?: string) {
return "详细内容";
}
// 或者
@Logger('event_get_detial2', (input, output) => {
return '我是自定义内容';
})
getDetial2(id?: string, category?: string) {
return "详细内容";
}
...
<button @click="getDetial2('1000', 'a')">获取详情</button>

效果: {logId: “event_get_detial2”, input: “getDetial(1000,a)”, output: “详细内容”, custom: “我是自定义内容”} , 每次点击按钮都会触发一次。

TODO: 这里还需要对输入参数和输出参数中的引用数据类型做处理。

同时还需要掌握: 装饰器工厂、装饰器组合、装饰器求值、参数装饰器、元数据

哪些功能适合用Decorator实现

官网和社区提供的这些Decorator, 可以作为自己框架的底层设计。

日志功能全局都得用,调用方法基本一致,是最适合使用装饰器来实现,并且每个项目的日志记录各有差异,最适合自定义这部分。

Decorator实现小Tips

考虑下各类Decorator叠加和共存的问题,可以参考官网关于装饰器组合描述
Decorator 的目标是在原有功能基础上,添加功能,切忌覆盖原有功能
类装饰器不能用在声明文件中( .d.ts),也不能用在任何外部上下文中(比如declare的类)
装饰器只能用于类和类的方法,不能用于函数,因为存在函数提升。类是不会提升的,所以就没有这方面的问题。