组件化开发

介绍

组件化什么时候在软件工程领域提出已经无从考究了,这个概念很早就被提出,近年来随着前端开发的迅速发展和工程化转变,组件化开发的思想也得到了进一步的发展和实践。我也是在前端开发中使用到Vue这个框架,接触到了组件化开发的思想。那什么是组件化呢?其实对(大)前端工程师来说很好理解,用一句话概括就是,接受外部数据输入,暴露特定事件的UI+逻辑组成的单元

对iOS工程师来说,系统提供的各种原生控件就是一种组件。例如一个输入框UITextField,它接受外部传入的初始值,接受用户输入,通过Delegate方式暴露出各种可以被关注的事件textChange。我们可以在xib/Storyboard/代码中方便的引入,用一个一个组件单元,组成我们的用户界面,同时监听我们所需的事件。对安卓工程师,也是一样的开发体验,各种原生的控件都相当的强大和方便。同时,当原生控件不能满足我们的需求时,我们也可以很方便的使用继承对原生控件进行扩展,比如添加子控件、添加自定义事件等,对于我们来说,开发手机客户端和搭积木非常相似,我们只需要选择合适的积木,按照一定的规则堆好就行了。

组件化.jpg

上图就是一个组件化开发的例子,页面分为Nav、List两个大的组件,List组件下包含了ListHeader、ListBody、ListFooter三个子组件,ListBody有包含若干ListCell组件,逻辑结构就可以表示成如下

<app>
  <Nav></Nav>
  <List>
    <ListHeader></ListHeader>
    <ListBody>
      <ListCell></ListCell>
      <ListCell></ListCell>
      ...
    </ListBody>
    <ListFooter></ListFooter>
  </List>
</app>

相信有客户端开发经验的同学看到这种结构一定非常熟悉——这不就是iOS里的Xib,Android中的Xml布局文件嘛!其实组件化的思想早已深入到了客户端开发中

Web组件化发展

而对于web前端来说,世界可能就没有那么美好了,我们没有那么多强大的控件得以使用,很多基础性的、公共的组件,浏览器都没有提供给我们,留给我们的只有

  • 简单的HTML标签
  • JS操作DOM的能力
  • CSS描述布局的功能。

在这种前提下,web前端初学者,包括我在初学的时候非常容易把代码写成意大利面条一样,所有的逻辑,比如ajax,更新DOM,更新数据等等都混杂在一起。这种写法在前端逻辑简单,界面层级不复杂的阶段是可行的,这种情况下引入框架反而会增加复杂性。

但随着前端的逐步发展以及前后端分离的开发趋势,现阶段的后端往往只提供数据,而不进行界面的构建和渲染,这样的好处就在于后端不必再给Web端提供专门的开发,而只需和手机客户端一样只提供接口和数据,让后端真正负责后台应该做的事情——处理业务逻辑、并发、分布式、缓存等等。这就要求前端处理更多的逻辑和渲染的工作,这是一个方面。另一方面,随着Google Mail Web版的横空出世,其与PC版几乎无异的流畅操作体验第一次把单页面应用(Single Page Application)带入人们的视线。于是,前端又有更多的事情要做了——路由、状态、本地存储、复杂动画。。。我们也把单页应用成为Web App,和iOS App、Android App等是平等的关系,开发的复杂程度也日趋接近。

所以,正如“人民日益增长的物质文化需求和落后的生产力之间的矛盾一样”,Web前端日益增长的需求和落后的开发标准和体验之间的矛盾,促使W3C标准的快速发展,从HTML5新增标签(也是组件的一种),到编程语言的发展ES5、ES6,以及Web的组件化标准Web Component`=,Web标准在一步一步走向完善,EmacScript更是加快到一年更新一个新版本。标准的制定是一回事,浏览器厂商的支持程度又是另一回事,目前的情况就是,虽然浏览器厂商积极的跟进Web标准,但距离主流浏览器完全实现还是有一定的距离,譬如组件化标准Web Components虽然很早提出但现在还没有定案。

正因为浏览器对组件化的支持程度不足,所以诞生了一系列的支持组件化的前端框架——Angular Directives、Ember Components、React Components、Vue.js Components等等,解决了前端开发的燃眉之急!

组件化的优势

下面以Vue组件为例,展示一下组件化开发的优势

1.可扩展

通过组件之间的合理组合搭配,可以构建出满足业务需求的新组件。
这一点很好理解,举个例子,我们有一个基础的树形组件treetree-node,现在来了一个业务需求,需要开发一个人员/机构的选择器,那么我们就可以很方便的基于我们的tree组件进行扩展,创建一个新的组件xx-selector

// xx-selector.vue
<template>
  <list :data="selectedData" /> // 已选列表
  </selected>
  <tree :data="treeData"  onSelect="onSelect">
    <template slot="treeNode">
      ...custom ui here
    </template>
  </tree> 
</template>

<script>
  import tree from ./tree.vue
  import list from ./list.vue
  module.exports = {
    data:{
      treeData:[],  
      selectedData:[]
    },
    created:function(){
      this.init()
    }
    methods:{
      onSelect:function(selected){
        this.selectedData = selected
        this.$emit('onSelectedChange',selected)
      },
      initData:function(){
        // ajax请求获取人员信息
      }
    }
  }
</script>

我们在逻辑代码部分加上诸如请求人员信息的接口、响应用户点击事件、响应全选/反选事件等等,这样就组成了一个功能完备的人员选择器组件。

2.可复用

刚才的xx-selector组件就复用到了基础的tree组件和tree-node组件。同样的道理,我们开发的xx-selector人员选择器组件,可以在任何有同样需求的地方重复使用,可以成为一个专属你们开发团队的一个基础组件,减少了开发量。

3.高内聚/低耦合

在我们使用xx-selector组件时,我们无需关心该组件内部的实现细节,我们只需要监听它暴露出来的onSelectedChanged(selectedList)事件,这个事件在选中人员发生改变时触发,把已选人员列表selectedList传递我们——我们使用选择器,所该关心就只是已选列表而已。

// my-app.vue
<template>
  <xx-selector onSelectedChanged="selectorChanged">
</template>
<script>
  import xx-selector from ./xx-selector.vue
  module.exports = {
    data:{ },
    methods:{
      selectorChanged:function(selected){
        // 处理已选
      }
    }
  }
</script>

这样就实现了

  • 组件内部高度内聚——只给外部提供功能,对外部的修改关闭
  • 组件之间低耦合——组件与组件只需要监听事件、触发事件,子组件不依赖与父组件

组件化的问题

正如《人月神话》中说到的——没有银弹,在软件工程中没有任何方法是完美的,组件化也有它的缺点,最明显的一点就是,当组件之间存在复杂和频繁的交流时,每一个组件都有可能修改系统的状态,由于多个状态分散的跨越在许多组件和交互间各个角落,大型应用复杂度也逐渐增长。

父子组件直接通信.png

通常在遇到这种情况的时候,Flux架构能较好的解决这种问题,通过单向数据流和统一的状态管理实现组件之间的依赖解耦。此时组件之间不再直接通信,而是通过修改共享的状态,去影响其他组件,间接得实现通信。这种方式在组件数量多、层次多时可以有效的降低复杂度。

Flux间接通信统一状态管理.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容