如何为Vue3提供一个可媲美Angular的ioc容器

 更新时间:2024年08月02日 10:05:50   作者:濮水大叔  
ue3因其出色的响应式系统,以及便利的功能特性,完全胜任大型业务系统的开发,这篇文章主要介绍了如何为Vue3提供一个可媲美Angular的ioc容器,需要的朋友可以参考下

为什么要为Vue3提供ioc容器

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

IOC容器分类

在 Zova 中有两类 ioc 容器:

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

Bean Class分类

Zova 采用模块化体系,Bean Class 都由不同的模块提供。使用模块内部的 Bean Class 时可以直接基于Class类型定位。在跨模块使用时可以基于Bean标识定位,而不是基于Class类型/文件路径定位,这样有利于实现模块之间的松耦合

因此,Zova 提供了两类 Bean Class:

  • 匿名bean:使用@Local装饰的 class 就是匿名bean。此类 bean 仅在模块内部使用,不存在命名冲突的问题,定义和使用都很便捷
  • 具名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 中通过injectionScope选项覆盖默认的注入范围

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', injectionScope: 'new' })
  $$modelTabs: ModelTabs;
}
  • 由于指定 injectionScope 选项为 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({ injectionScope: 'host' })
  $$modelTabs: ModelTabs;
}
  • 由于父组件已经注入了 ModelTabs 的 bean 实例,因此子组件可以直接查找并注入
  • 层级注入同样支持所有注入机制:Bean Class/Bean标识/注册名/变量名

5. skipSelf

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

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

到此这篇关于如何为Vue3提供一个可媲美Angular的ioc容器的文章就介绍到这了,更多相关Vue3 ioc容器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue实现多个tab标签页的切换与关闭详细代码

    vue实现多个tab标签页的切换与关闭详细代码

    这篇文章主要给大家介绍了关于vue实现多个tab标签页的切换与关闭的相关资料,使用vue.js实现tab切换很简单,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • vue使用neovis操作neo4j图形数据库及优缺点

    vue使用neovis操作neo4j图形数据库及优缺点

    这篇文章主要介绍了vue使用neovis操作neo4j图形数据库,本文给大家介绍了与常规做法的优缺点对比及使用技巧,对vue neo4j图形数据库相关知识感兴趣的朋友一起看看吧
    2022-02-02
  • 解决vue项目打包上服务器显示404错误,本地没出错的问题

    解决vue项目打包上服务器显示404错误,本地没出错的问题

    这篇文章主要介绍了解决vue项目打包上服务器显示404错误,本地没出错的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • typescript+vite项目配置别名的方法实现

    typescript+vite项目配置别名的方法实现

    我们为了省略冗长的路径,经常喜欢配置路径别名,本文主要介绍了typescript+vite项目配置别名的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 五种Vue实现加减乘除运算的方法总结

    五种Vue实现加减乘除运算的方法总结

    这篇文章主要为大家详细介绍了五种Vue实现加减乘除运算的方法,文中的示例代码简洁易懂,对我们深入了解vue有一定的帮助,需要的可以了解下
    2023-08-08
  • vue-cli2.0转3.0之项目搭建的详细步骤

    vue-cli2.0转3.0之项目搭建的详细步骤

    这篇文章主要介绍了vue-cli2.0转3.0之项目搭建的详细步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • Vue图片裁剪功能实现代码

    Vue图片裁剪功能实现代码

    这篇文章主要介绍了Vue图片裁剪功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • 解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题

    解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题

    这篇文章主要介绍了解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • VUE跳转外部链接与网页的方法示例

    VUE跳转外部链接与网页的方法示例

    这篇文章主要给大家介绍了关于VUE跳转外部链接与网页的方法,记录一下在vue项目中如何实现跳转到一个新页面,需要的朋友可以参考下
    2023-06-06
  • vue实现图片路径转二进制文件流(binary)

    vue实现图片路径转二进制文件流(binary)

    这篇文章主要介绍了vue实现图片路径转二进制文件流(binary),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06

最新评论