用户界面是由一系列组件组合而成,组件将数据和交互封装在内,仅保留必要的接口与其余组件进行通讯。html
从抽象的角度来看,任何用户界面都是由组件
、数据
和交互
组成的。前端
组件是一个具备必定功能的独立单元,不一样的组件能够组合在一块儿,构成功能更强大的组件,组件是网页的器官
。
组件的概念要和HTML标签的概念区分开来,HTML标签是网页的基本单元,而组件是基于HTML标签的、包含特定功能的独立单元,能够简单理解为组件是HTML标签的一个超集。
组件内部封装的是数据和交互,对外暴露必要的接口,以与其余组件进行通讯。react
用户界面中包含不少数据,有不变的静态数据,也有随时间和交互改变的动态数据,它们大多来自于后台数据库。
组件内部包含数据,组件之间传递的也是数据,数据是网页的核心
。
在前端开发中,数据主要以JSON格式进行存储和传递。git
交互是用户的操做,主要经过鼠标和键盘等计算机外设触发,点击一次按钮、在文本框中输入一些字符、按下回车键等都是交互。
在网页中,全部的交互都是经过事件的方式进行响应的。
交互是网页的灵魂
,不能进行交互的网页就像干涸的河流,了无生气。github
一个设计良好的组件应该包含如下特性:
复用性(Reuseability)
、组合性(Composability)
和扩展性(Scalability)
。数据库
组件做为一个独立的单元,除了自身的特定功能以外,不该该包含任何业务相关的数据。
组件应该可以复用到任何业务中,只要该业务须要用到组件所包含的功能。
组件应该是资源独立的,以加强组件的复用能力。antd
组件与组件之间能够像积木同样进行组合,组合以后的组件拥有子组件的全部功能,变得更强大。
组合的方式能够是包裹别的组件,也能够是做为参数传入别的组件中。函数
能够基于现有的组件进行扩展,开发功能更加定制化的组件,以知足业务需求。
组件的可扩展能力依赖于接口的设计,接口要尽量的灵活,以应对不断变化的需求。布局
经过props
将数据传递到组件内部,以供组件自身或其子组件使用。
props是不可变的,这意味着咱们没法在组件内部修改props的原始值,也意味着只有外部传入了props,才能在组件内部获取和使用它。spa
能够经过两种方式将组件内部的数据传递到组件外,一是经过ref
属性(组件实例的引用),二是经过事件回调
(好比:onClick)
能够经过全局context
的方式进行双向通讯。
父组件声明context对象,那么其下全部的子组件,无论嵌套多深,均可以使用该对象的数据,而且能够经过回调函数的方式将子组件的数据传递出来供父组件使用。
经过事件订阅的方式能够实现多个组件之间互相通讯。
经过自定义事件(Custom Event)
,任何组件均可以与其余组件进行通信,采用的是发布/订阅模式,经过向事件对象上添加监听和触发事件来实现组件间通讯。
接下来经过广告详情页面的开发来演示如何用积木理论来构建网页。
设计图以下:
将设计图拆分红有层次的积木结构。
最顶层拆分红四个大积木:
其中的div标签是为了布局方便加入的。
每一个大积木又能够拆分红若干小积木,中间层有些是不可拆分的原子积木,好比:Button、Checkbox;有些是由原子积木组合而成的复合积木,好比:DateRangePicker、Table。层次结构以下:
最底层的积木都是不可拆分的原子积木。
已经将积木的层次结构设计出来,接下来就要考虑每一个层次的积木怎么制造的问题。
因为广告详情涉及的积木众多,这里仅举日期选择组件(DatePicker)的例子来讲明制造积木的方法,具体见如下连接:
日期选择组件
对应的代码:
<div className="ad-detail-container"> <Header /> <div className="content"> <div className="chart-detail-block"> <ChartBlock /> <DetailBlock /> </div> <TableBlock /> </div> </div>
Header对应的代码:
<div className="header"> <div className="breadcrumb-area"> <div className="breadcrumb-current">gary audio</div> <div className="breadcrumb-from">From: <Breadcrumb className="breadcrumb" separator=""> <BreadcrumbItem href="http://www.qq.com">Campaign List</BreadcrumbItem> <span className="breadcrumb-seprator">> </span> <BreadcrumbItem href="http://www.qq.com">gary audio test</BreadcrumbItem> </Breadcrumb></div> </div> <div className="operation-area"> <Button icon="mail" className="flat" onClick={() => { console.log('You click "Send Report Email" button'); }}>Send Report Email</Button> <DateRangePicker onChange={(selectedDate) => { console.log('selected date:', selectedDate); }} /> </div> </div>
须要注意的是:为了方便阐述积木理论的核心思想,这里的原子组件大多都是已经造好的(使用antd组件库),也能够选择本身制造,后面会举例如何本身制造组件。
ChartBlock对应的代码:
<div className="chart-block"> <Tabs defaultActiveKey="1"> <TabItem tab={<div className="tab-title">Ad performance</div>} key="1"> <LineChart /> </TabItem> <TabItem tab={<div className="tab-title">Audience</div>} key="2"> <BarChart /> </TabItem> </Tabs> </div>
DetailBlock对应的代码:
<div className="detail-block"> <div className="detail-header"> <div className="detail-title">Ad detail</div> <div className="detail-operation"> <Button icon="edit" className="flat" onClick={() => { console.log('You click "Edit" button'); }}>Edit</Button> <Button icon="delete" className="flat" onClick={() => { console.log('You click "Delete" button'); }}>Delete</Button> <Button icon="eye" className="flat" onClick={() => { console.log('You click "Preview" button'); }}>Preview</Button> </div> </div> <List data={adDetail} config={detailConfig} /> </div>
TableBlock对应的代码:
<div className="table-block"> <div className="table-operation-bar"> <Checkbox onChange={(event) => { console.log('Your checked status: ', event.target.checked); }}>Has delivery</Checkbox> <Select className="select-table-column" defaultValue="1" onChange={(value) => { console.log('You selected: ', value); }}> <Option value="1">Performance</Option> <Option value="2">Customize</Option> </Select> <Button icon="export" onClick={() => { console.log('You click "Export Data" button'); }}>Export Data</Button> </div> <Table dataSource={adsList} columns={columns} /> </div>
因为篇幅缘由,这个案例并无包含交互的部分,不过基本可以阐述清楚积木理论的核心思想。
案例源码:
前端开发积木理论案例