Skip to content

具名bean: Store

除了@Local之外,其他装饰器函数装饰的 class 都是具名bean。Zova 为此类 bean 提供了命名规范,既可以避免命名冲突,也有利于跨模块使用

Store bean就是一种具名 bean,我们先通过store bean来了解具名 bean 的定义和使用方式

通过 store bean 我们可以定义一个全局的状态对象,然后在任何一个模块中使用。因此,不再需要使用pinia。如果要使用已经存在的pinia store,参见:Pinia

创建Store Bean: userInfo

我们先来创建一个 store bean userInfo。可以通过 cli 命令创建 store bean 的代码骨架:

bash
$ zova :create:store userInfo --module=a-demo

src/suite/a-demo/modules/a-demo/src/bean/store.userInfo.ts

typescript
@Store()
export class StoreUserInfo {}
  • Store 是装饰器函数。通过 Store 装饰的 class 会自动注册到 bean 容器中

添加响应式代码

我们在userInfo中添加一个响应式属性user,并且进行异步初始化

typescript
interface User {
  name: string;
  age: number;
}

@Store()
export class StoreUserInfo {
  user: User;

  protected async __init__() {
    this.user = await this.loadUser();
  }

  private async loadUser(): Promise<User> {
    return new Promise(resolve => {
      window.setTimeout(() => {
        resolve({ name: 'tom', age: 18 });
      }, 500);
    });
  }

  public async reloadUser() {
    this.user = await this.loadUser();
  }
}

使用Store Bean

接下来通过 cli 命令创建一个 local bean testC

bash
$ zova :create:local testC --module=a-demo

然后直接在testC中注入userInfo,并访问其中的属性和方法

src/suite/a-demo/modules/a-demo/src/testC.ts

typescript
import { StoreUserInfo } from './bean/store.userInfo.js';

export class TestC {
  @Use()
  $$userInfo: StoreUserInfo;

  protected async __init__() {
    console.log(this.$$userInfo.user);
    await this.$$userInfo.reloadUser();
  }
}
  • 通过Use装饰器函数会自动在 app bean 容器中查找或者创建一个 store 实例,然后注入到testC
  • $$userInfo的类型设置为StoreUserInfo,app bean 容器将根据此类型找到 class 并创建一个实例

跨模块使用

刚才演示的是在当前模块中使用 store bean,现在我们看看如何跨模块使用

Bean标识

在 Zova 中,一个模块就是一个天然的拆包边界,在 build 构建时,自动打包成一个独立的异步 Chunk

因此,在跨模块使用 store bean 时,我们不建议直接基于类型注入,而是基于标识注入

系统会为每一个 store bean 自动分配一个标识,格式如下:

bash
{moduleName}.store.{beanName}

比如,前面创建的 userInfo,对应的标识为:a-demo.store.userInfo,其中a-demouserInfo所归属的模块名称

跨模块使用Store Bean

接下来通过 cli 命令创建一个模块a-demo2,同时创建一个 local bean testD

bash
$ zova :create:module a-demo2 --template=basic --suite=a-demo
$ pnpm install --force
$ zova :create:local testD --module=a-demo2

然后直接在testD中注入userInfo,并访问其中的属性和方法

src/suite/a-demo/modules/a-demo2/src/testD.ts

typescript
import type { StoreUserInfo } from 'zova-module-a-demo';

export class TestD {
  @Use('a-demo.store.userInfo')
  $$userInfo: StoreUserInfo;

  protected async __init__() {
    console.log(this.$$userInfo.user);
    await this.$$userInfo.reloadUser();
  }
}
  • zova-module-a-demo模块导入 class StoreUserInfo的类型
  • Use装饰器函数传入 store bean 的标识,在这里就是a-demo.store.userInfo。系统会自动在 app bean 容器中通过 bean 标识来查找或者创建一个 store 实例,然后注入到testD

基于 MIT 许可发布