首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

加油,为Vue3提供一个可媲美Angular的ioc容器

编程知识
2024年07月31日 15:48

为什么要为Vue3提供ioc容器

Vue3因其出色的响应式系统,以及便利的功能特性,完全胜任大型业务系统的开发。但是,我们不仅要能做到,而且要做得更好。大型业务系统的关键就是解耦合,从而减缓shi山代码的生长。而ioc容器是目前最好的解耦合工具。Angular从一开始就引入了ioc容器,因此在业务工程化方面一直处于领先地位,并且一直在向其他前端框架招手:“我在前面等你们,希望三年后能再见”。那么,我就试着向前走两步,在Vue3中引入ioc容器,并以此为基础扩充其他工程能力,得到一个新框架:Zova。诸君觉得是否好用,欢迎拍砖、交流:

IOC容器分类

在 Zova 中有两类 ioc 容器:

  1. 全局ioc容器:在系统初始化时,会自动创建唯一一个全局 ioc 容器。在这个容器中创建的Bean实例都是单例模式
  2. 组件实例ioc容器:在创建 Vue 组件实例时,系统会为每一个 Vue 组件实例创建一个 ioc 容器。在这个容器中创建的Bean实例可以在组件实例范围之内共享数据和逻辑

Bean Class分类

在 Zova 中有两类 Bean Class:

  1. 匿名bean:使用@Local装饰的 class 就是匿名bean。此类 bean 仅在模块内部使用,不存在命名冲突的问题,定义和使用都很便捷
  2. 具名bean:除了@Local之外,其他装饰器函数装饰的 class 都是具名bean。Zova 为此类 bean 提供了命名规范,既可以避免命名冲突,也有利于跨模块使用

注入机制

Zova 通过@Use装饰器函数注入 Bean 实例,提供了以下几种注入机制:

1. Bean Class

通过Bean Class在 ioc 容器中查找并注入 Bean 实例,如果不存在则自动创建。这种机制一般用于同模块注入

import { ModelTodo } from '../../bean/model.todo.js';

class ControllerTodo {
  @Use()
  $$modelTodo: ModelTodo;
}

2. Bean标识

通过Bean标识在 ioc 容器中查找并注入 Bean 实例,如果不存在则自动创建。这种机制一般用于跨模块注入层级注入

import type { ModelTabs } from 'zova-module-a-tabs';

class ControllerLayout {
  @Use('a-tabs.model.tabs')
  $$modelTabs: ModelTabs;
}
  • 通过a-tabs.model.tabs查找并注入 Bean 实例
  • 因此,只需导入 ModelTabs 的 type 类型,从而保持模块之间的松耦合关系

3. 注册名

通过注册名在 ioc 容器中查找并注入 Bean 实例,如果不存在则返回空值。这种机制一般用于同模块注入层级注入

import type { ModelTodo } from '../../bean/model.todo.js';

class ControllerTodo {
  @Use({ name: '$$modelTodo' })
  $$modelTodo: ModelTodo;
}
  • 通过注册名$$modelTodo查找并注入 Bean 实例。一般而言,应该确保在 ioc 容器中已经事先注入过 Bean 实例,否则就会返回空值

4. 属性名

通过属性名在 ioc 容器中查找并注入 Bean 实例,如果不存在则返回空值。这种机制一般用于同模块注入层级注入

import type { ModelTodo } from '../../bean/model.todo.js';

class ControllerTodo {
  @Use()
  $$modelTodo: ModelTodo;
}
  • 通过属性名$$modelTodo查找并注入 Bean 实例。一般而言,应该确保在 ioc 容器中已经事先注入过 Bean 实例,否则就会返回空值

注入范围

匿名bean的默认注入范围都是ctx具名bean可以在定义时指定默认注入范围,不同的场景(scene)有不同的默认注入范围。 此外,在实际注入时,还可以在@Use 中通过containerScope选项覆盖默认的注入范围

Zova 提供了以下几种注入范围:app/ctx/new/host/skipSelf

1. app

如果注入范围是 app,那么就在全局 ioc 容器中注入 bean 实例,从而实现单例的效果

// in module: test-module1
@Store()
class StoreCounter {}
// in module: test-module2
import type { StoreCounter } from 'zova-module-test-module1';

class Test {
  @Use('test-module1.store.counter')
  $$storeCounter: StoreCounter;
}
  • Store 的注入范围默认是 app,因此通过 Bean 标识test-module1.store.counter在全局 ioc 容器中查找并注入 bean 实例

2. ctx

如果注入范围是 ctx,那么就在当前组件实例的 ioc 容器中注入 bean 实例

// in module: a-tabs
@Model()
class ModelTabs {}
// in module: test-module2
import type { ModelTabs } from 'zova-module-a-tabs';

class ControllerLayout {
  @Use('a-tabs.model.tabs')
  $$modelTabs: ModelTabs;
}
  • Model 的注入范围默认是 ctx,因此通过 Bean 标识a-tabs.model.tabs在当前组件实例的 ioc 容器中查找并注入 bean 实例

3. new

如果注入范围是 new,那么就直接创建新的 bean 实例

// in module: a-tabs
@Model()
class ModelTabs {}
// in module: test-module2
import type { ModelTabs } from 'zova-module-a-tabs';

class ControllerLayout {
  @Use({ beanFullName: 'a-tabs.model.tabs', containerScope: 'new' })
  $$modelTabs: ModelTabs;
}
  • 由于指定 containerScope 选项为 new,因此通过 Bean 标识a-tabs.model.tabs直接创建新的 bean 实例

层级注入

注入范围除了支持app/ctx/new,还支持层级注入:host/skipSelf

4. host

如果注入范围是 host,那么就在当前组件实例的 ioc 容器以及所有父容器中依次查找并注入 bean 实例,如果不存在则返回空值

// in parent component
import type { ModelTabs } from 'zova-module-a-tabs';

class Parent {
  @Use('a-tabs.model.tabs')
  $$modelTabs: ModelTabs;
}
// in child component
import type { ModelTabs } from 'zova-module-a-tabs';

class Child {
  @Use({ containerScope: 'host' })
  $$modelTabs: ModelTabs;
}
  • 由于父组件已经注入了 ModelTabs 的 bean 实例,因此子组件可以直接查找并注入
  • 层级注入同样支持所有注入机制:Bean Class/Bean标识/注册名/属性名

5. skipSelf

如果注入范围是 skipSelf,那么就在所有父容器中依次查找并注入 bean 实例,如果不存在则返回空值

Zova已开源:https://github.com/cabloy/zova

From:https://www.cnblogs.com/zhennann/p/18334979
本文地址: http://www.shuzixingkong.net/article/636
0评论
提交 加载更多评论
其他文章 概述C#中各种类型集合的特点
在C#中,集合是用于存储和操作一组数据项的数据结构。这些集合通常位于 System.Collections 和 System.Collections.Generic 命名空间中。下面我将概述C#中几种常用的集合类型及其特点: 1. System.Collections 命名空间中的集合 这个命名空间
概述C#中各种类型集合的特点
结合拦截器描述mybatis启动流程
简介 mybatis的启动入口一般有两个,在结合spring框架后由spring整合包下的SqlSessionFactoryBean启动 如果没有整合spring,则有XMLConfigBuilder启动 这两个启动入口都会初始化Configuration对象,该对象是mybatis配置文件的对象形
结合拦截器描述mybatis启动流程
SQL实战从在职到离职(1) 如何处理连续查询
书接上回,最近离职在家了实在无聊,除了看看考研的书,打打dnf手游,也就只能写写代码,结果昨晚挂在某平台的一个技术出售有人下单了,大概业务是需要帮忙辅导一些面试需要用到的SQL。 回想了下,在该平台接单SQL也超过3w元了,考察的也就是那几大类,我准备开一个新的专题,把我遇到的题目做一些示例和总结,
SQL实战从在职到离职(1) 如何处理连续查询
nacos配置&gateway配置服务发现一直报500
项目场景: 这两天不是一直在搞简化配置、使用公共配置、我的服务可以通过网关访问这几个任务嘛,也是不断地踩坑补知识才总算把这几个任务都搞好了,下面就是记录过程中遇到的问题。 使用公共配置 因为发现项目使用的配置文件过多,有application、application-test.yml、bootstr
DNS在架构中的使用
1 介绍 DNS(Domain Name System,域名系统)是一种服务,它是域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP地址数串。 简单来说,DNS就是一个将我们输入的网址(比如www.baidu.com )转换成对应的IP地址(比
DNS在架构中的使用 DNS在架构中的使用 DNS在架构中的使用
《最新出炉》系列初窥篇-Python+Playwright自动化测试-60 - 判断元素是否显示 - 下篇
1.简介 有些页面元素的生命周期如同流星一闪,昙花一现。我们也不知道这个元素在没在页面中出现过,为了捕获这一美好瞬间,让其成为永恒。我们就来判断元素是否显示出现过。 在操作元素之前,可以先判断元素的状态。判断元素操作状态也可以用于断言。 2.常用的元素判断方法 2.1page对象调用的判断方法 pa
《最新出炉》系列初窥篇-Python+Playwright自动化测试-60 - 判断元素是否显示 - 下篇 《最新出炉》系列初窥篇-Python+Playwright自动化测试-60 - 判断元素是否显示 - 下篇 《最新出炉》系列初窥篇-Python+Playwright自动化测试-60 - 判断元素是否显示 - 下篇
SSH Exporter:基于Prometheus的远程系统性能监控神器
SSH Exporter English | 中文 介绍 SSH Exporter 是一个基于 Prometheus 规范的监控工具,通过 SSH 协议远程收集目标服务器的系统性能数据,如 CPU 使用率、内存使用情况、磁盘和网络 I/O 等,并将这些数据暴露为 Prometheus 格式的 met
全网最适合入门的面向对象编程教程:29 类和对象的Python实现-断言与防御性编程和help函数的使用
在Python中,断言是一种常用的调试工具,它允许程序员编写一条检查某个条件。本文主要介绍了断言的应用场景和特点以及assert语句的使用,同时介绍了防御性编程和help()函数。
全网最适合入门的面向对象编程教程:29 类和对象的Python实现-断言与防御性编程和help函数的使用 全网最适合入门的面向对象编程教程:29 类和对象的Python实现-断言与防御性编程和help函数的使用 全网最适合入门的面向对象编程教程:29 类和对象的Python实现-断言与防御性编程和help函数的使用