VonaJS AOP编程:魔术方法

在VonaJS框架中,AOP编程包括三方面:控制器切面内部切面外部切面内部切面包括两个能力:AOP Method魔术方法。这里我们简要介绍一下魔术方法的用法。

魔术方法

魔术方法,允许我们在 Class 内部通过__get____set__切入动态属性或方法

举例:Module Scope

为了让 IOC 容器的使用更加简洁和直观,VonaJS 推荐优先使用依赖查找策略,从而使用更少的装饰器函数,使用更少的类型标注。通过Module Scope对象访问模块提供的资源,就是践行依赖查找策略的机制之一

比如,模块 demo-student 中有一个 model student,用于 crud 操作。可以这样使用 model:

typescript 复制代码
import { ModelStudent } from '../model/student.ts';

async findMany(params) {
  const model = this.bean._getBean(ModelStudent);
  return await model.selectAndCount(params);
}

使用魔术方法:

typescript 复制代码
async findMany(params) {
  return await this.scope.model.student.selectAndCount(params);
}
  • this.scope.model.xxx: 通过魔术方法动态获取当前模块中的 model 实例

举例:CRUD(魔术方法)

Vona ORM 采用魔术方法的机制进一步简化操作数据的代码

比如,通过字段id查询学生信息,代码如下:

typescript 复制代码
async findOne(id) {
  return await this.scope.model.student.get({ id });
}

使用魔术方法:

typescript 复制代码
async findOne(id) {
  return await this.scope.model.student.getById(id);
}
  • 系统自动从 method name getById中解析出参数id,然后调用实际的 CRUD 方法,这里就是: get({ id })

创建Class

可以在任何 Class 中实现魔术方法。下面,以 Service 为例,在模块 demo-student 中创建一个 Service color,代码如下:

  • 如何创建 Service,参见: Service
typescript 复制代码
import { BeanBase } from 'vona';
import { Service } from 'vona-module-a-bean';

@Service()
export class ServiceColor extends BeanBase {}

__get__

然后,通过__get__实现颜色值的获取

1. 添加代码骨架

在 VSCode 编辑器中,输入代码片段aopmagicget,自动生成代码骨架:

diff 复制代码
@Service()
export class ServiceColor extends BeanBase {
+ protected __get__(prop: string) {}
}

2. 实现自定义逻辑

diff 复制代码
@Service()
export class ServiceColor extends BeanBase {
+ private _colors = {
+   red: '#FF0000',
+   green: '#00FF00',
+   blue: '#0000FF',
+ };

  protected __get__(prop: string) {
+   return this._colors[prop];
  }
}

3. 添加类型合并

通过接口类型合并的机制为颜色提供类型定义

typescript 复制代码
export interface ServiceColor {
  red: string;
  green: string;
  blue: string;
}

4. 使用魔术方法

typescript 复制代码
async test() {
  console.log(this.scope.service.color.red);
  console.log(this.scope.service.color.green);
  console.log(this.scope.service.color.blue);
}

__set__

然后,通过__set__实现颜色值的设置

1. 添加代码骨架

在 VSCode 编辑器中,输入代码片段aopmagicset,自动生成代码骨架:

diff 复制代码
@Service()
export class ServiceColor extends BeanBase {
+ protected __set__(prop: string, value: any): boolean {
+   return false;
+ }
}

2. 实现自定义逻辑

diff 复制代码
@Service()
export class ServiceColor extends BeanBase {
  private _colors = {
    red: '#FF0000',
    green: '#00FF00',
    blue: '#0000FF',
+   black: '',
  };

  protected __set__(prop: string, value: any): boolean {
+   if (this._colors[prop] === undefined) return false;
+   this._colors[prop] = value;
+   return true;
  }
}
  • 如果为prop设置了值,返回true,否则返回false

3. 添加类型合并

通过接口类型合并的机制为颜色提供类型定义

diff 复制代码
export interface ServiceColor {
  red: string;
  green: string;
  blue: string;
+ black: string;
}

4. 使用魔术方法

typescript 复制代码
async test() {
  this.scope.service.color.black = '#000000';
  console.log(this.scope.service.color.black);
}

资源

相关推荐
小二李1 天前
第15章 NestJS 项目部署
nestjs
前端踩bug工程师2 天前
nestjs 实现一对多,多对一,一对一在实现上的区别
nestjs
右耳朵猫AI3 天前
Web前端周刊2026W38 | React 19.3 发布、StyleX 深潜、jsdom 30.1 提速
前端·javascript·react.js·typescript·node.js
溪语流沙3 天前
Django + Vue电商项目第001讲:开篇|注册登录加增删改查,那不是电商
redis·python·mysql·docker·typescript·django·vue
掰头战士4 天前
多重影分身!恨不得把一个agent掰成两个? 还真能干!
typescript·llm·agent
shmily麻瓜小菜鸡4 天前
TDD(测试驱动开发)详解
开发语言·javascript·typescript·node.js·ecmascript
雾隐隐o4 天前
TypeScript 基础:数据类型、接口与类型推论
typescript
flash俊杰5 天前
Zod Schema 驱动的 IPC 契约:从入参校验到状态机一致性的三层防御
javascript·typescript
愛芳芳5 天前
基于 Electron + Vue3 的仿 PC 微信客户端项目实战
前端·javascript·css·elementui·typescript·electron·vue
神秘的猪头6 天前
TypeScript 高级用法全解析:从泛型到 infer,把类型系统真正用起来
前端·typescript