第145篇:js设计模式注册模式及相应实践
好家伙,
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 包在方法内部是一种良好的编程实践,有利于提高代码的可维护性、可读性,并且能够更好地控制数据的访问权限和作用域。
第145篇:js设计模式注册模式及相应实践的更多相关文章
- PHP设计模式 -- 注册模式
参考文章:https://segmentfault.com/a/1190000007495855 简介 注册树模式又称注册模式或注册器模式.注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候 ...
- js设计模式--迭代器模式
迭代器模式: 迭代器模式提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该方法中的内部表示.js中我们经常会封装一个each函数用来实现迭代器. 理解的意思:提供一个方法,去把对象的每一项按 ...
- js设计模式--单体模式
GOF里的23种设计模式, 也是在软件开发中早就存在并反复使用的模式. 如果程序员没有明确意识到他使用过某些模式, 那么下次他也许会错过更合适的设计 (这段话来自<松本行弘的程序世界>). ...
- [转]js设计模式-策略模式
在程序设计中,常常遇到类似的情况,要实现某一个功能有多种方案可以选择.比如一个压缩文件的程序,既可以选择zip算法,也可以选择gzip算法.这些算法灵活多样,而且可以随意互相替换.这种解决方案就是本文 ...
- 如何做JS 单体模式的设计---->>js设计模式<<-------单体模式
1. 单体模式是js中最基本 单最有用的模式之一,非常常用. 单体模式的基本结构如下: var Person = { name: 'lilu', age:', sayHi: function(){ a ...
- JS设计模式——工厂模式详解
它的领域中同其它模式的不同之处在于它并没有明确要求我们使用一个构造器.取而代之,一个工厂能提供一个创建对象的公共接口,我们可以在其中指定我们希望被创建的工厂对象的类型. 简单工厂模式:使用一个类(通常 ...
- 浅谈js设计模式 — 命令模式
命令模式最常见的应用场景是:有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么.此时希望用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦 ...
- js设计模式-命令模式
命令模式是一种组织型模式,主要用在把调用对象(用户界面.API和代理等)与实现操作的对象隔离开.也就是说 ,凡是两个对象间的互动方式需要更高的模块化程度时都可以用到这种模式. 命令模式的好处:1.提高 ...
- js设计模式-组合模式
组合模式是一种专为创建web上的动态用户界面而量身定制的模式.使用这种模式,可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更容易维护,而那些复杂行为则被委托给各个对象. ...
- js设计模式-桥接模式
桥接模式定义:桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化".这句话有三个关键词,也就是抽象化.实现化和 ...
随机推荐
- C语言中位运算取余
位运算取余 求一个数被另一个数整除的余数,可以用求余运算符"%",但是,如果不允许使用求余运算符,又该怎么办呢?下面介绍一种方法,是通过位运算来求余,但是注意:该方法只对除数是2的 ...
- Js中Symbol对象
Js中Symbol对象 ES6引入了一种新的基本数据类型Symbol,表示独一无二的值,最大的用法是用来定义对象的唯一属性名,Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方 ...
- C++ 多线程的错误和如何避免(10)
线程中的异常可以使用 std::rethrow_exception 抛给主线程 问题分析:一个线程中抛出的异常是没法被另一个线程捕获的.假如我们在主线程中创建一个子线程,子线程中的函数抛出了异常,主线 ...
- C++ 多线程的错误和如何避免(1)
在终止程序之前没有使用 join() 等待后台线程 前提分析:线程分为 joinable 状态和 detached 状态 添加 .join() 这句代码的时候,就表示主线程需要等待子线程运行结束回收 ...
- python中动态生成类type的用法
示例:正常创建类 class Person(object): def __init__(self): self.name = name self.age = age p = Person(" ...
- core-js/modules/es7.arrat......................报错
拉入代码之后出现如图提示,导致原因是因为core-js版本太高,可以用cnpm install core-js@2成功解决,安装一个项目前最后将node-moudel删除,重新安装
- 【Azure事件中心】使用Python SDK(Confluent)相关方法获取offset或lag时提示SSL相关错误
问题描述 使用Python SDK(Confluent)相关方法获取offset或lag时, 提示SSL相关错误, 是否有更清晰的实例以便参考呢? 问题解决 执行代码,因为一直连接不成功,所以检查 c ...
- 【Azure 应用服务】App Service运行时突然中断:There is not enough space on the disk : 'D:localTempASPNETCORE...
问题描述 App Service运行过程中,突然出现了 There is not enough space on the disk : 'D:localTempASPNETCORE_xxxxxx-xx ...
- Glide源码解析四(解码和转码)
本文基于Glide 4.11.0 Glide加载过程有一个解码过程,比如将url加载为inputStream后,要将inputStream解码为Bitmap. 从Glide源码解析一我们大致知道了Gl ...
- C++ auto与循环
C++ auto与循环 C++ auto 的介绍 typeid(p).name();可以输出auto的类型 auto 是 C++11 引入的一个关键字,用于自动类型推导.编译器会根据初始化表达式的类型 ...