facing-dev/vue-facing-decorator

能否添加两个切面装饰器:@Intercept和@Catch

Groupguanfang opened this issue · 1 comments

我自己的项目里面已经手写了一个,目的就是为了抽离额外的逻辑。

但是目前还有点简陋,如果可以的话等我搞好了再提个PR啥的吧。

都上装饰器了,为何这个仓库不内置一个切面编程的装饰器呢?模仿Nest.js,一个@Catch一个@Intercept:

  • @Catch: ClassDecorator
  • @Intercept: MethodDecorator

框架内部到时候导出一个TS interface模型, 比如叫VueInterceptor:

export interface VueInterceptor {
  /**
   * 前置拦截
   *
   * @param {Record<string, any>} this
   * @return {*}
   * @memberof VueInterceptor
   */
  before?(this: Record<string, any>): any
  /**
   * 后置拦截
   *
   * @param {Record<string, any>} this
   * @return {*}
   * @memberof VueInterceptor
   */
  after?(this: Record<string, any>): any
  /**
   * 异常拦截
   *
   * @param {Record<string, any>} this
   * @param {*} error
   * @return {*}
   * @memberof VueInterceptor
   */
  catch?(this: Record<string, any>, error: any): any
  /**
   * 最终拦截
   *
   * @param {Record<string, any>} this
   * @return {*}
   * @memberof VueInterceptor
   */
  finally?(this: Record<string, any>): any
}

开发者使用时,先定义一个切面类,实现VueInterceptor接口:

@Catch(AxiosError)
export class TestInterceptor implements VueInterceptor {
  before(this: TestComponent) {
    // 前置操作
  }

  after(this: TestComponent) {
    // 后置操作 如果出现错误不会执行这个方法里的代码
  }

  catch(this: TestComponent, error: Error) {
    // 错误处理
    // if (error instanceof AxiosError) 吧啦吧啦之类的
  }

  finally(this: TestComponent) {
    // 无论如何都会在最后执行
  }
}

因为每个方法上的第一个参数都是this: TestComponent,所以当执行this.xxx的时候会有TestComponent类上的类型提示,所以类型提示也是非常完备的。

其中,@Catch装饰器允许传递参数,具体的用法可以和nest.js一样,即:

  • 不传参,拦截所有的错误;
  • 传了参,拦截指定的错误(通过instanceof判断)

在组件上使用:

@Component
export default class TestComponent extends Vue {
  // 直接用@Intercept装饰器new这个类就行
  @Intercept(new TestInterceptor())
  testMethod() {}
}

这样其实相当于就是把try/catch/finally三板斧抽出来了,让组件方法更加符合直觉,只处理具体的逻辑而不是被一整片的错误处理等的额外代码所干扰。

这不是v-f-d的内容,可以创建一个新的库来实现这些功能。