Skip to content

vfd 中提供了自定义装饰器的封装,接下来就通过实现一个 AOP 开发中一个典型的日志输出装饰器。

接下来通过改造 14组合式API应用 中的代码来实现一个打印当前执行的方法名称的日志输出装饰器。

vue
<script lang="ts">
import { Component, Setup, Vue } from 'vue-facing-decorator'
import { useRouter, Router } from 'vue-router'
import Log from './decorator/index';
  
@Component
export default class App extends Vue {
  @Setup(() => useRouter())
  router!: Router;

  @Log()
  goto(path: string) {
    this.router.push({ path });
  }
  
}
</script>

vfd 模块中导出 createDecoratorcreateDecorator 需要接收一个回调函数,在这个回调函数被触发时,可以通过它的参数获取到 组件的选项(方便进行修改),还会获得装饰器所在的类属性或方法的名称。

在下面实现的装饰器中是一个典型的函数扩展,首先会将 xx 函数的功能保存到 original ,接着就是用一个新的函数来重写原先的功能,在新编写的函数中会使用 apply 对原函数的功能进行执行。这样就可以在不丢失原有函数功能的前提下对函数进行扩展了。

typescript
import { createDecorator } from 'vue-facing-decorator';

function Log() {
  return createDecorator(
    function (options, key) {
      const original = options.methods?.[key];
      if (original) {
        options.methods[key] = function (...args: any[]) {
          original.apply(this, args);
          console.log(`The ${key} function is executed`)
        }
      }
    },
    {
      preserve: true,
    }
  );
}

export default Log;

[^注]: 需要装饰器所描述的类属性或类方法需要再装饰器生效前保留,需要开启 preserve 选项,在上面的案例中很显然我们是需要得到所描述的方法的,故进行了开启。