好傢伙,
0.索引
在阿里的低開專案中,使用這種形式去註冊元件,我不禁好奇,這到底是個什麼玩意
1.概念
在 JavaScript 中,註冊模式(Registry Pattern)是一種設計模式,它用於管理物件、函式或其他型別的例項,並提供一種機制來訪問它們。註冊模式通常用於將物件例項註冊到一箇中心登錄檔中,以便在需要時能夠輕鬆地檢索和使用這些例項。
註冊模式通常包含以下幾個核心元件:
-
登錄檔(Registry):登錄檔是一個儲存物件例項的集合,通常以鍵值對的形式儲存。可以將物件例項註冊到登錄檔中,也可以從登錄檔中檢索物件例項。
-
註冊(Registration):註冊是指將物件例項新增到登錄檔中的過程。通常會將物件例項與一個唯一的識別符號(如字串)相關聯,以便在需要時能夠透過該識別符號檢索物件例項。
-
檢索(Retrieval):檢索是指從登錄檔中獲取物件例項的過程。透過提供相應的識別符號,可以從登錄檔中檢索相應的物件例項。
使用註冊模式的一個常見場景是在應用程式中管理和訪問多個服務、外掛或元件。透過將這些服務、外掛或元件註冊到一箇中心登錄檔中,可以在需要時輕鬆地獲取它們,而無需直接引用它們的實現細節。
2.實踐
然後我發現我的低開物料庫也能這麼幹,
具體怎麼做呢?
1.寫個登錄檔
2.寫個註冊方法
3.寫出相應的檢索方法
3.登錄檔
const componentList = [];
以陣列的形式存在,可以直接push
4.註冊方法
function createEditorConfig() {
const componentList = [];
return {
componentList,
componentMap,
register: (component) => {
componentList.push(component);
}
};
}
5.檢索
function createEditorConfig() {
const componentList = [];
const componentMap = {};
console.log(componentList,componentMap)
return {
componentList,
componentMap,
register: (component) => {
componentList.push(component);
componentMap[component.key] = component;
}
};
}
export let registerConfig = createEditorConfig();
registerConfig.register({
label: '文字',
preview: () => '預覽文字',
render: function(h) {
return h('div', '渲染文字');
},
key: 'text'
});
registerConfig.register({
label: '按鈕',
preview: () => <ElButton>預覽按鈕</ElButton>,
render: function(h) {
return <el-button>渲染按鈕</el-button>;
},
key: 'button'
});
registerConfig.register({
label: '輸入框',
preview: () => <ElInput placeholder="預覽輸入框">預覽按鈕</ElInput>,
render: function(h) {
return <el-input placeholder="渲染輸入框">預覽輸入框</el-input>;
},
key: 'input'
});
這裡,我們為每個註冊的元件配置配置相應的key值(比如輸入框元件的key值是input)
componentMap
是一個物件,用於將元件的 key與元件物件進行對映。
當註冊一個新元件時,會將元件物件以 key-value 的形式儲存在 componentMap
物件中,其中 key 是元件的唯一識別符號,通常用於查詢特定元件。
透過維護一個元件對映,可以快速透過 key 查詢到對應的元件物件。
6.使用登錄檔
既然登錄檔已經做好了,那麼我們去將這個登錄檔中的元件渲染出來
<div class="material" v-for="(component, key) in registerConfig.componentMap" :key="component.key">
<span>{{ key }}</span>
<component :is="component"></component>
</div>
components: {
lcEditor, lcRender, test, Material,
component: {
functional: true,
render(h, { data }) {
return h(registerConfig.componentMap[data.key]);
}
}
},
成功渲染
7.疑問:為什麼要將componentList,componentMap包在方法內部?
將 componentList
和 componentMap
包在 createEditorConfig
方法內部的主要目的是為了封裝這兩個變數,並且透過閉包的方式建立了一個私有作用域,避免了這兩個變數被外部直接訪問和修改。
具體原因如下:
-
封裝資料: 將
componentList
和componentMap
包在方法內部,可以將它們視為createEditorConfig
方法的私有屬性,外部無法直接訪問或修改這兩個變數,只能透過register
方法來操作它們,從而保證了資料的封裝性。 -
避免全域性汙染: 將變數包在方法內部可以避免將這些變數暴露在全域性作用域中,減少了全域性變數的數量,避免了可能出現的命名衝突和全域性汙染。
-
提供了私有作用域: 透過閉包的方式,
register
方法可以訪問到componentList
和componentMap
變數,但外部無法直接訪問這兩個變數,確保了資料的私有性。 -
簡化呼叫方式: 將
componentList
和componentMap
封裝在方法內部,使得建立配置物件和註冊元件的操作更加簡潔明瞭,只需呼叫createEditorConfig()
方法即可獲得一個包含componentList
和componentMap
的配置物件,然後透過register
方法註冊元件。
總的來說,將 componentList
和 componentMap
包在方法內部是一種良好的程式設計實踐,有利於提高程式碼的可維護性、可讀性,並且能夠更好地控制資料的訪問許可權和作用域。