如何為Vue3提供一個(gè)可媲美Angular的ioc容器
為什么要為Vue3提供ioc容器
Vue3因其出色的響應(yīng)式系統(tǒng),以及便利的功能特性,完全勝任大型業(yè)務(wù)系統(tǒng)的開(kāi)發(fā)。但是,我們不僅要能做到,而且要做得更好。大型業(yè)務(wù)系統(tǒng)的關(guān)鍵就是解耦合,從而減緩shi山代碼的生長(zhǎng)。而ioc容器是目前最好的解耦合工具。Angular從一開(kāi)始就引入了ioc容器,因此在業(yè)務(wù)工程化方面一直處于領(lǐng)先地位,并且一直在向其他前端框架招手:“我在前面等你們,希望三年后能再見(jiàn)”。那么,我就試著向前走兩步,在Vue3中引入ioc容器,并以此為基礎(chǔ)擴(kuò)充其他工程能力,得到一個(gè)新框架:Zova。諸君覺(jué)得是否好用,歡迎拍磚、交流:
IOC容器分類(lèi)
在 Zova 中有兩類(lèi) ioc 容器:
全局ioc容器
:在系統(tǒng)初始化時(shí),會(huì)自動(dòng)創(chuàng)建唯一一個(gè)全局 ioc 容器。在這個(gè)容器中創(chuàng)建的Bean實(shí)例都是單例模式組件實(shí)例ioc容器
:在創(chuàng)建 Vue 組件實(shí)例時(shí),系統(tǒng)會(huì)為每一個(gè) Vue 組件實(shí)例創(chuàng)建一個(gè) ioc 容器。在這個(gè)容器中創(chuàng)建的Bean實(shí)例可以在組件實(shí)例范圍之內(nèi)共享數(shù)據(jù)和邏輯
Bean Class分類(lèi)
Zova 采用模塊化體系,Bean Class 都由不同的模塊提供。使用模塊內(nèi)部的 Bean Class 時(shí)可以直接基于Class類(lèi)型
定位。在跨模塊使用時(shí)可以基于Bean標(biāo)識(shí)
定位,而不是基于Class類(lèi)型/文件路徑
定位,這樣有利于實(shí)現(xiàn)模塊之間的松耦合
因此,Zova 提供了兩類(lèi) Bean Class:
匿名bean
:使用@Local
裝飾的 class 就是匿名bean
。此類(lèi) bean 僅在模塊內(nèi)部使用,不存在命名沖突的問(wèn)題,定義和使用都很便捷具名bean
:除了@Local
之外,其他裝飾器函數(shù)裝飾的 class 都是具名bean
。Zova 為此類(lèi) bean 提供了命名規(guī)范,既可以避免命名沖突,也有利于跨模塊使用
注入機(jī)制
Zova 通過(guò)@Use
裝飾器函數(shù)注入 Bean 實(shí)例,提供了以下幾種注入機(jī)制:
1. Bean Class
通過(guò)Bean Class
在 ioc 容器中查找并注入 Bean 實(shí)例,如果不存在則自動(dòng)創(chuàng)建。這種機(jī)制一般用于同模塊注入
import { ModelTodo } from '../../bean/model.todo.js'; class ControllerTodo { @Use() $$modelTodo: ModelTodo; }
2. Bean標(biāo)識(shí)
通過(guò)Bean標(biāo)識(shí)
在 ioc 容器中查找并注入 Bean 實(shí)例,如果不存在則自動(dòng)創(chuàng)建。這種機(jī)制一般用于跨模塊注入
和層級(jí)注入
import type { ModelTabs } from 'zova-module-a-tabs'; class ControllerLayout { @Use('a-tabs.model.tabs') $$modelTabs: ModelTabs; }
- 通過(guò)
a-tabs.model.tabs
查找并注入 Bean 實(shí)例 - 因此,只需導(dǎo)入 ModelTabs 的 type 類(lèi)型,從而保持模塊之間的松耦合關(guān)系
3. 注冊(cè)名
通過(guò)注冊(cè)名
在 ioc 容器中查找并注入 Bean 實(shí)例,如果不存在則返回空值。這種機(jī)制一般用于同模塊注入
和層級(jí)注入
import type { ModelTodo } from '../../bean/model.todo.js'; class ControllerTodo { @Use({ name: '$$modelTodo' }) $$modelTodo: ModelTodo; }
- 通過(guò)注冊(cè)名
$$modelTodo
查找并注入 Bean 實(shí)例。一般而言,應(yīng)該確保在 ioc 容器中已經(jīng)事先注入過(guò) Bean 實(shí)例,否則就會(huì)返回空值
4. 變量名
通過(guò)變量名
在 ioc 容器中查找并注入 Bean 實(shí)例,如果不存在則返回空值。這種機(jī)制一般用于同模塊注入
和層級(jí)注入
import type { ModelTodo } from '../../bean/model.todo.js'; class ControllerTodo { @Use() $$modelTodo: ModelTodo; }
- 通過(guò)變量名
$$modelTodo
查找并注入 Bean 實(shí)例。一般而言,應(yīng)該確保在 ioc 容器中已經(jīng)事先注入過(guò) Bean 實(shí)例,否則就會(huì)返回空值
注入范圍
匿名bean
的默認(rèn)注入范圍都是ctx
,具名bean
可以在定義時(shí)指定默認(rèn)注入范圍,不同的場(chǎng)景(scene)有不同的默認(rèn)注入范圍。 此外,在實(shí)際注入時(shí),還可以在@Use 中通過(guò)injectionScope
選項(xiàng)覆蓋默認(rèn)的注入范圍
Zova 提供了以下幾種注入范圍:app/ctx/new/host/skipSelf
1. app
如果注入范圍是 app,那么就在全局 ioc 容器中注入 bean 實(shí)例,從而實(shí)現(xiàn)單例的效果
// 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 的注入范圍默認(rèn)是 app,因此通過(guò) Bean 標(biāo)識(shí)
test-module1.store.counter
在全局 ioc 容器中查找并注入 bean 實(shí)例
2. ctx
如果注入范圍是 ctx,那么就在當(dāng)前組件實(shí)例的 ioc 容器中注入 bean 實(shí)例
// 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 的注入范圍默認(rèn)是 ctx,因此通過(guò) Bean 標(biāo)識(shí)
a-tabs.model.tabs
在當(dāng)前組件實(shí)例的 ioc 容器中查找并注入 bean 實(shí)例
3. new
如果注入范圍是 new,那么就直接創(chuàng)建新的 bean 實(shí)例
// 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 選項(xiàng)為 new,因此通過(guò) Bean 標(biāo)識(shí)
a-tabs.model.tabs
直接創(chuàng)建新的 bean 實(shí)例
層級(jí)注入
注入范圍除了支持app/ctx/new
,還支持層級(jí)注入:host/skipSelf
4. host
如果注入范圍是 host,那么就在當(dāng)前組件實(shí)例的 ioc 容器以及所有父容器中依次查找并注入 bean 實(shí)例,如果不存在則返回空值
// 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; }
- 由于父組件已經(jīng)注入了 ModelTabs 的 bean 實(shí)例,因此子組件可以直接查找并注入
層級(jí)注入
同樣支持所有注入機(jī)制:Bean Class/Bean標(biāo)識(shí)/注冊(cè)名/變量名
5. skipSelf
如果注入范圍是 skipSelf,那么就在所有父容器中依次查找并注入 bean 實(shí)例,如果不存在則返回空值
Zova已開(kāi)源:https://github.com/cabloy/zova
到此這篇關(guān)于如何為Vue3提供一個(gè)可媲美Angular的ioc容器的文章就介紹到這了,更多相關(guān)Vue3 ioc容器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實(shí)現(xiàn)多個(gè)tab標(biāo)簽頁(yè)的切換與關(guān)閉詳細(xì)代碼
這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)多個(gè)tab標(biāo)簽頁(yè)的切換與關(guān)閉的相關(guān)資料,使用vue.js實(shí)現(xiàn)tab切換很簡(jiǎn)單,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10vue使用neovis操作neo4j圖形數(shù)據(jù)庫(kù)及優(yōu)缺點(diǎn)
這篇文章主要介紹了vue使用neovis操作neo4j圖形數(shù)據(jù)庫(kù),本文給大家介紹了與常規(guī)做法的優(yōu)缺點(diǎn)對(duì)比及使用技巧,對(duì)vue?neo4j圖形數(shù)據(jù)庫(kù)相關(guān)知識(shí)感興趣的朋友一起看看吧2022-02-02解決vue項(xiàng)目打包上服務(wù)器顯示404錯(cuò)誤,本地沒(méi)出錯(cuò)的問(wèn)題
這篇文章主要介紹了解決vue項(xiàng)目打包上服務(wù)器顯示404錯(cuò)誤,本地沒(méi)出錯(cuò)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11typescript+vite項(xiàng)目配置別名的方法實(shí)現(xiàn)
我們?yōu)榱耸÷匀唛L(zhǎng)的路徑,經(jīng)常喜歡配置路徑別名,本文主要介紹了typescript+vite項(xiàng)目配置別名的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07五種Vue實(shí)現(xiàn)加減乘除運(yùn)算的方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了五種Vue實(shí)現(xiàn)加減乘除運(yùn)算的方法,文中的示例代碼簡(jiǎn)潔易懂,對(duì)我們深入了解vue有一定的幫助,需要的可以了解下2023-08-08vue-cli2.0轉(zhuǎn)3.0之項(xiàng)目搭建的詳細(xì)步驟
這篇文章主要介紹了vue-cli2.0轉(zhuǎn)3.0之項(xiàng)目搭建的詳細(xì)步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12解決Vue-cli3沒(méi)有vue.config.js文件夾及配置vue項(xiàng)目域名的問(wèn)題
這篇文章主要介紹了解決Vue-cli3沒(méi)有vue.config.js文件夾及配置vue項(xiàng)目域名的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12VUE跳轉(zhuǎn)外部鏈接與網(wǎng)頁(yè)的方法示例
這篇文章主要給大家介紹了關(guān)于VUE跳轉(zhuǎn)外部鏈接與網(wǎng)頁(yè)的方法,記錄一下在vue項(xiàng)目中如何實(shí)現(xiàn)跳轉(zhuǎn)到一個(gè)新頁(yè)面,需要的朋友可以參考下2023-06-06vue實(shí)現(xiàn)圖片路徑轉(zhuǎn)二進(jìn)制文件流(binary)
這篇文章主要介紹了vue實(shí)現(xiàn)圖片路徑轉(zhuǎn)二進(jìn)制文件流(binary),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06