这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战

背景

在初入安卓开发的阶段要为一个按钮绑定点击事件需要经过

  1. 通过ID查找视图
  2. 为视图添加监听方法
  3. 完成点击事件具体内容

后来引入了一些IOC的库使得第1步和第2步可以通过配置自动完成,我们只关心点击事件的具体逻辑处理即可。
在前端MVVM框架盛行的现在,我们的事件绑定已经相当的简单了,但还是会有时候用到传统的写法,我们通过改造传统的前端事件绑定的写法了了解一下TypeScript中方法装饰器的使用。

HTML中只有视图的声明
  1. <button id="query">查询</button>
  2. <button id="cancel">取消</button>
  1. const queryNode = document.querySelector("#query");
  2. queryNode?.addEventListener("click", function () {
  3. console.log("发起请求,查询数据~");
  4. });

从上面的代码看的出前端的事件绑定和安卓中事件绑定的流程一致,都需要查找视图,添加监听方法,编写事件具体内容,重复的事情我们交给程序自动完成,专心写好查询函数。

引入接口来规范传入的参数

  • 参数1:绑定视图的ID
  • 参数2:绑定事件的名称
    1. interface EventOptions {
    2. id: string;
    3. event: string;
    4. }

    创建方法装饰器

  1. 方法装饰器在运行时会当做函数传入以下三个参数来供我们使用
    • 参数1:原型对象
    • 参数2:成员名
    • 参数3:属性描述符
  2. 说明:

    • 装饰器函数中使用到了闭包
    • 通过参数1和2可以灵活定位函数
      1. function bindEvent(options: EventOptions) {
      2. const { id, event } = options;
      3. return function (
      4. target: any, // ①原型对象
      5. propertyKey: string, // ②成员的名字
      6. descriptor: PropertyDescriptor // ③成员的属性描述符
      7. ) {
      8. const node = document.querySelector(`#${id}`);
      9. node?.addEventListener(event, function () {
      10. 执行函数
      11. target[propertyKey]();
      12. });
      13. };
      14. }

      模拟类组件进行装饰

      ```typescript export class Component { @bindEvent({ id: “query”, event: “click” }) query() { console.log(“发起请求,查询数据~”); }

    @bindEvent({ id: “cancel”, event: “click” }) cancel() { console.log(“接口取消~”); } } ``` 现在就可以将视图的ID和待绑定的事件类型传入装饰器进行配置,我们就专心完成点击事件的具体功能吧。