前端通用组件设计

JavaScript026

前端通用组件设计,第1张

调用组件库的API相信很多人都会用,但是如何封装一个高复用的组件并不是每个人都能做到,而这也是检验一个前端开发人员的一个标准。

说到开发组件,首先需要考虑一个问题,一个可复用的组件都需要具备哪些必要条件。

1. 细粒度考量

看过设计模式的朋友应该有了解过很多设计原则,其中一个就是 单一职责原则 ,这个原则放在开发组件中也同样适用。在原则上一个组件就只负责一件事,这就是单一原则所带来的好处也非常明显,就是可以更大可能的复用组件。但如果职责过于单一,也会造成组件碎片化严重,过于抽象。

因此我们需要考虑,所谓的单一职责原则是建立在可复用的基础上的。否则,可以做为独立组件的内部组件进行使用。

2. 组件通用性考量

组件设计之初是为了当时的页面设计进行封装设计的,那么之后的页面设计极大可能是与之前不同的,那么之前设计的组件就不能用了。

而一旦发生这样的情况,就说明我们之前所设计的组件是不通用的,需要重新设计了。就像Antd组件库那样,预留了dropdownRender进行组件渲染。

通用性的设计就代表着将放弃对DOM的操作权,暴露给开发者进行操作,组件开发者本身只负责底层逻辑和基本的DOM结构。这也是开发通用型组件的秘诀之一。

3. 技术选型

css存在着许多的弊端,例如样式易冲突(没有作用域的概念)、书写繁琐(不支持嵌套)、缺少变量(不便于一件更换主题)等等。而解决这些问题的方案也是层出不穷,从最早的css预处理,到后来的Postcss,再到后来的styled-compontent,各种方式任君选择。

4. 打包工具

产品的设计思想固然是核心,但是也需要一堆辅助工具来来帮助我们开发,例如编译工具、测试工具、打包工具。

说到打包工具,就不得不提一下如今非常火爆的,需要配置工程师专门配置的webpack了。但是他也有一个强大的竞争对手 rollup。

rollup更适合用于组件库的打包,优势如下:

设计一个轮播图组件

学以致用,学了就肯定要实践一下。轮播图是一个比较常见的组件,每个组件库中都封装的有,接下来我们也来介绍一下如何设计一个轮播图组件。

1. 轮播图原理

通常情况下我们使用轮播图是这样编写的

那么为什么放入了四个div盒子却只显示一个呢,这是因为可视区域是固定的,只需要移动div盒子就可以显示出后面的盒子,这样就达到了轮播的效果。

为了是观看效果更好,我们都会隐藏掉可视区域之外的内容,这样就是大家经常看到的轮播图了。组件就可以这样设计:

可以通过transform: translateX()不断改变SlideList的位置,就可以达到轮播的效果了。

2. 轮播图的基础实现

知道了基础原理就可以进行组件的实现了,这里以移动端轮播图为例。

首先,获取移动端可视窗口的宽度。

------- 未完待续 --------

他们是一个东西,没什么区别。js组件就是把一系列的功能封装起来,包装成一个对象。比如一个表格组件,一个表单组件等等。一个组件必然包含了某种特定的职能,目的在于可以复用。比方说,你的网站需要展示一个万年历,那么最基本的方法,就是自己画table,自己写逻辑,麻烦得一笔。假如我有100个页面,那么是不是说我要把这些代码复制100遍??所以,为了避免这种麻烦,就可以把万年历封装成一个组件,然后做成一个js文件发布,别人下载就行了。

一、MVC

MVC模式的意思是,软件可以分成三个部分。

视图(View):用户界面。

控制器(Controller):业务逻辑

模型(Model):数据保存

各部分之间的通信方式如下。

View 传送指令到 Controller

Controller 完成业务逻辑后,要求 Model 改变状态

Model 将新的数据发送到 View,用户得到反馈

所有通信都是单向的。

二、互动模式

接受用户指令时,MVC 可以分成两种方式。一种是通过 View 接受指令,传递给 Controller。

另一种是直接通过controller接受指令。

三、实例:Backbone

实际项目往往采用更灵活的方式,以 Backbone.js 为例。

1. 用户可以向 View 发送指令(DOM 事件),再由 View 直接要求 Model 改变状态。

2. 用户也可以直接向 Controller 发送指令(改变 URL 触发 hashChange 事件),再由 Controller 发送给 View。

3. Controller 非常薄,只起到路由的作用,而 View 非常厚,业务逻辑都部署在 View。所以,Backbone 索性取消了 Controller,只保留一个 Router(路由器) 。

四、MVP

MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向。

1. 各部分之间的通信,都是双向的。

2. View 与 Model 不发生联系,都通过 Presenter 传递。

3. View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。

五、MVVM

MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。

唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。 Angular 和 Ember 都采用这种模式。

1、js工厂模式

说明:

在函数中定义对象,并定义对象的各种属性,虽然属性可以为方法,但是建议将属性为方法的属性定义到函数之外,这样可以避免重复创建该方法。

引用该对象的时候,这里使用的是 var x = Parent()而不是 var x = new object()因为后者可能会出现很多问题(前者也成为工厂经典方式,后者称之为混合工厂方式),不推荐使用new的方式使用该对象。

在函数的最后返回该对象。

不推荐使用这种方式创建对象,但应该了解。  

2、js构造函数模式

说明:

与工厂方式相比,使用构造函数方式创建对象无需在函数内部创建对象,而使用this指代,并而函数无需明确return。

同工厂模式一样,虽然属性的值可以为方法,仍建议将该方法定义在函数之外。

同样的,不推荐使用这种方式创建对象,但仍需了解。

3、js原型模式

说明:

函数中不对属性进行定义。

利用prototype属性对属性进行定义。

同样的额,不推荐使用这样的方式创建对象。

4、构造函数+原型的js混合模式(推荐)

说明:

该模式是指混合搭配使用构造函数和原型方式。

将所有的属性,不是方法的定义在函数中(构造函数的方式),将所有属性值为方法的利用prototype在函数之外定义(原型方式)。

推荐使用这样的方式创建对象,这样有好处。

5、构造函数+原型的动态原型模式(推荐)

说明:

动态原型方式可以理解为混合构造函数,原型方式的一个特例。

该模式中,属性为方法的属性直接在函数中进行了定义,但是因为

if(typeof Parent.lev == "undefined"){

          Parent.prototype.lev = function(){

            return this.name

          }

   Parent.lev = true

    } 

从而保证创建该对象的实例时,属性的方法不会被重复的创建。