菜单

组件化的Web王国

2019年10月5日 - Bootstrap

致大家自然组件化的Web

2015/11/25 · HTML5 · 1
评论
·
组件化

原稿出处:
AlloyTeam   

那篇作品将从五年前的二遍才具争论起来。龃龉的聚焦正是下图的四个目录分层结构。我说按模块划分好,他说你傻逼啊,当然是按财富划分。

manbetx2.0手机版 1 《=》manbetx2.0手机版 2

”按模块划分“目录结构,把如今模块下的持有逻辑和能源都放一块了,那对于四人独立开采和保卫安全个人模块不是很好吧?当然了,那争执的结果是本身婴孩地改回主流的”按能源划分“的目录结构。因为,未有完成JS模块化和能源模块化,仅仅物理地点上的模块划分是尚未意思的,只会扩大营造的资本而已。

虽说她说得好有道理小编哑口无言,可是本身心不甘,等待她近来端组件化成熟了,再来世界一战!

而后天就是自个儿珍视提议正义的光景!只是那时极度跟你撕逼的人不在。

模块化的青黄不接

模块平时指能够独立拆分且通用的代码单元。由于JavaScript语言本人未有内置的模块机制(ES6有了!!),大家经常会动用CMD或ADM建立起模块机制。现在比非常多稍稍大型一点的类型,都会使用requirejs可能seajs来兑现JS的模块化。四人分工合营开辟,其分别定义信赖和暴光接口,维护成效模块间独立性,对于项目标付出效能和种类早先时期扩大和保卫安全,都以是有一点都不小的帮带效能。

但,麻烦我们不怎么略读一下底下的代码

JavaScript

require([
‘Tmpl!../tmpl/list.html’,’lib/qqapi’,’module/position’,’module/refresh’,’module/page’,’module/net’
], function(listTmpl, QQapi, Position, Refresh, Page, NET){ var foo =
”, bar = []; QQapi.report(); Position.getLocaiton(function(data){
//… }); var init = function(){ bind();
NET.get(‘/cgi-bin/xxx/xxx’,function(data){ renderA(data.banner);
renderB(data.list); }); }; var processData = function(){ }; var bind =
function(){ }; var renderA = function(){ }; var renderB =
function(data){ listTmpl.render(‘#listContent’,processData(data)); };
var refresh = function(){ Page.refresh(); }; // app start init(); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
require([
    ‘Tmpl!../tmpl/list.html’,’lib/qqapi’,’module/position’,’module/refresh’,’module/page’,’module/net’
], function(listTmpl, QQapi, Position, Refresh, Page, NET){
    var foo = ”,
        bar = [];
    QQapi.report();
    Position.getLocaiton(function(data){
        //…
    });
    var init = function(){
        bind();
        NET.get(‘/cgi-bin/xxx/xxx’,function(data){
            renderA(data.banner);
            renderB(data.list);
        });
    };
    var processData = function(){
    };
    var bind = function(){
    };
    var renderA = function(){
    };
    var renderB = function(data){
        listTmpl.render(‘#listContent’,processData(data));
    };
    var refresh = function(){
        Page.refresh();
    };
    // app start
    init();
});

地方是切实某些页面包车型大巴主js,已经封装了像Position,NET,Refresh等功效模块,但页面包车型大巴主逻辑照旧是”面向进程“的代码结构。所谓面向进程,是指依照页面包车型客车渲染进度来编排代码结构。像:init
-> getData -> processData -> bindevent -> report -> xxx

方法之间线性跳转,你大概也能感受那样代码缺陷。随着页面逻辑更是复杂,那条”进度线“也会更为长,並且越来越绕。加之缺少专门的职业约束,其余类型成员根据各自须要,在”进度线“加插各自逻辑,最后这几个页面包车型客车逻辑变得难以维护。

manbetx2.0手机版 3

支付要求一步一个鞋的痕迹,生怕影响“进度线”后边寻常逻辑。何况每一回加插或退换都以bug泛滥,无不令产品有关职员一律惶惶不安。

 页面结构模块化

听大人讲上面包车型大巴面向进程的标题,行当内也会有大多减轻方案,而笔者辈协会也总计出一套成熟的缓和方案:Abstractjs,页面结构模块化。大家得以把大家的页面想象为叁个乐高机器人,须要区别零件组装,如下图,假如页面划分为tabContainer,listContainer和imgsContainer八个模块。最后把那么些模块add到结尾的pageModel里面,最后利用rock方法让页面运转起来。

manbetx2.0手机版 4
(原经过线示例图)

manbetx2.0手机版 5
(页面结构化示例图)

上边是伪代码的贯彻

JavaScript

require([
‘Tmpl!../tmpl/list.html’,’Tmpl!../tmpl/imgs.html’,’lib/qqapi’,’module/refresh’,’module/page’
], function(listTmpl, imgsTmpl, QQapi, Refresh, Page ){ var
tabContainer = new RenderModel({ renderContainer: ‘#tabWrap’, data: {},
renderTmpl: “<li soda-repeat=’item in
data.tabs’>{{item}}</li>”, event: function(){ // tab’s event }
}); var listContainer = new ScrollModel({ scrollEl: $.os.ios ?
$(‘#Page’) : window, renderContainer: ‘#listWrap’, renderTmpl:
listTmpl, cgiName: ‘/cgi-bin/index-list?num=1’, processData:
function(data) { //… }, event: function(){ // listElement’s event },
error: function(data) { Page.show(‘数据再次来到十分[‘ + data.retcode +
‘]’); } }); var imgsContainer = new renderModel({ renderContainer:
‘#imgsWrap’, renderTmpl: listTmpl, cgiName: ‘/cgi-bin/getPics’,
processData: function(data) { //… }, event: function(){ //
imgsElement’s event }, complete: function(data) { QQapi.report(); } });
var page = new PageModel();
page.add([tabContainer,listContainer,imgsContainer]); page.rock(); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
require([
    ‘Tmpl!../tmpl/list.html’,’Tmpl!../tmpl/imgs.html’,’lib/qqapi’,’module/refresh’,’module/page’
], function(listTmpl, imgsTmpl, QQapi, Refresh, Page ){
 
    var tabContainer = new RenderModel({
        renderContainer: ‘#tabWrap’,
        data: {},
        renderTmpl: "<li soda-repeat=’item in data.tabs’>{{item}}</li>",
        event: function(){
            // tab’s event
        }
    });
 
    var listContainer = new ScrollModel({
        scrollEl: $.os.ios ? $(‘#Page’) : window,
        renderContainer: ‘#listWrap’,
        renderTmpl: listTmpl,
        cgiName: ‘/cgi-bin/index-list?num=1’,
        processData: function(data) {
            //…
        },
        event: function(){
            // listElement’s event
        },
        error: function(data) {
            Page.show(‘数据返回异常[‘ + data.retcode + ‘]’);
        }
    });
 
    var imgsContainer = new renderModel({
        renderContainer: ‘#imgsWrap’,
        renderTmpl: listTmpl,
        cgiName: ‘/cgi-bin/getPics’,
        processData: function(data) {
            //…
        },
        event: function(){
            // imgsElement’s event
        },
        complete: function(data) {
           QQapi.report();
        }
    });
 
    var page = new PageModel();
    page.add([tabContainer,listContainer,imgsContainer]);
    page.rock();
 
});

咱俩把那一个常用的央浼CGI,管理数据,事件绑定,上报,容错处理等一种类逻辑方式,以页面块为单位封装成二个Model模块。

那般的八个华而不实层Model,大家能够清晰地察看该页面块,诉求的CGI是何许,绑定了怎么风浪,做了何等上报,出错怎么管理。新扩展的代码就应该放置在相应的模块上相应的事态方法(preload,process,event,complete…),杜绝了以前的无准则乱增代码的写作。并且,依据不一样工作逻辑封装分裂类别的Model,如列表滚动的ScrollModel,滑块成效的SliderModel等等,能够拓宽中度封装,集中优化。

当今基于Model的页面结构开采,已经包蕴一点”组件化“的暗意。每一种Model都包涵各自的多寡,模板,逻辑。已经算是四个完好的机能单元。但相差真正的WebComponent依然有一段距离,起码满意不断笔者的”理想目录结构“。

 WebComponents 标准

大家回想一下选择二个datapicker的jquery的插件,所须求的步奏:

  1. 引进插件js

  2. 引进插件所需的css(借使有)

  3. copy 组件的所需的html片段

  4. 累加代码触发组件运维

方今的“组件”基本上只好到达是有个别意义单元上的聚合。他的能源都以松散地分散在二种能源文件中,并且组件成效域揭破在大局意义域下,缺少内聚性很轻松就能够跟别的零件爆发争辩,如最简便的css命名龃龉。对于这种“组件”,还不比下面的页面结构模块化。

于是W3C按耐不住了,制订二个WebComponents标准,为组件化的前景指导了明路。

上面以较为轻便的章程介绍那份正经,力求我们能够高效驾驭达成组件化的剧情。(对那部分询问的同室,能够跳过这一小节)

1. <template>模板技艺

模板那东西南开学家最了解可是了,前年见的相当多的沙盘品质大战artTemplate,juicer,tmpl,underscoretemplate等等。而明日又有mustachejs无逻辑模板引擎等新入选手。可是大家有未有想过,这么基础的技术,原生HTML5是不扶助的(T_T)。

方今日WebComponent将要提供原生的模版技巧

XHTML

<template id=”datapcikerTmpl”>
<div>作者是原生的模板</div> </template>

1
2
3
<template id="datapcikerTmpl">
<div>我是原生的模板</div>
</template>

template标签钦赐义了myTmpl的模板,供给动用的时候就要innerHTML= document.querySelector('#myTmpl').content;能够观察这么些原生的沙盘够原始,模板占位符等功效都未有,对于动态数据渲染模板本事只可以自力更新。

2. ShadowDom 封装组件独立的内部结构

ShadowDom能够知道为一份有单独成效域的html片段。那么些html片段的CSS情况和主文书档案隔断的,各自小编保护持内部的独立性。也多亏ShadowDom的独门脾气,使得组件化成为了大概。

JavaScript

var wrap = document.querySelector(‘#wrap’); var shadow =
wrap.createShadowRoot(); shadow.innerHTML = ‘<p>you can not see me
</p>’

1
2
3
var wrap = document.querySelector(‘#wrap’);
var shadow = wrap.createShadowRoot();
shadow.innerHTML = ‘<p>you can not see me </p>’

在切实可行dom节点上选择createShadowRoot方法就可以生成其ShadowDom。就像是在整份Html的房内面,新建了三个shadow的屋企。房间外的人都不通晓房间内有何,保持shadowDom的独立性。

3. 自定义原生标签

首先接触Angularjs的directive指令功用,设定好组件的逻辑后,二个<Datepicker
/>就能够引进整个组件。如此狂光彩夺目炸碉堡天的效率,实在令人大快人心,跃地三尺。

JavaScript

var tmpl = document.querySelector(‘#datapickerTmpl’); var
datapickerProto = Object.create(HTMLElement.prototype); //
设置把大家模板内容我们的shadowDom datapickerProto.createdCallback =
function() { var root = this.createShadowRoot();
root.appendChild(document.importNode(tmpl.content, true)); }; var
datapicker = docuemnt.registerElement(‘datapicker’,{ prototype:
datapickerProto });

1
2
3
4
5
6
7
8
9
10
11
12
var tmpl = document.querySelector(‘#datapickerTmpl’);
var datapickerProto = Object.create(HTMLElement.prototype);
 
// 设置把我们模板内容我们的shadowDom
datapickerProto.createdCallback = function() {
    var root = this.createShadowRoot();
    root.appendChild(document.importNode(tmpl.content, true));
};
 
var datapicker = docuemnt.registerElement(‘datapicker’,{
    prototype: datapickerProto
});

Object.create方式继续HTMLElement.prototype,获得贰个新的prototype。当分析器开掘大家在文书档案中标志它将检查是还是不是八个名称叫createdCallback的措施。假诺找到这么些主意它将随即运行它,所以我们把克隆模板的剧情来创设的ShadowDom。

manbetx2.0手机版,最后,registerElement的办法传递大家的prototype来注册自定义标签。

上边的代码开首略显复杂了,把前面四个力量“模板”“shadowDom”结合,变成组件的当中逻辑。最终经过registerElement的方式注册组件。之后能够愉悦地<datapicker></datapicker>的选拔。

4. imports减轻组件间的借助

XHTML

<link rel=”import” href=”datapciker.html”>

1
<link rel="import" href="datapciker.html">

那些类php最常用的html导入成效,HTML原生也能支撑了。

WebComponents规范内容大致到此处,是的,小编这里未有啥德姆o,也从未实施经验分享。由于webComponents新特点,基本上巳了高版本的Chrome帮忙外,其余浏览器的协助度甚少。纵然有polymer援救推动webcompoents的仓库储存在,可是polymer自己的供给版本也是极度高(IE10+)。所在此以前几天的顶梁柱并不是他。

大家大概来回看一下WebCompoents的四局地效率:

1 .<template>定义组件的HTML模板本领

  1. Shadow Dom封装组件的内部结构,並且维持其独立性

  2. Custom Element 对外提供组件的价签,完结自定义标签

  3. import解决组件结合和信任性加载

 组件化推行方案

官方的专门的学问看完了,大家想想一下。一份真正成熟笃定的组件化方案,要求全体的力量。

“能源高内聚”—— 组件财富内部高内聚,组件财富由作者加载调节

“成效域独立”—— 内部结构密闭,不与大局或其余零件产生影响

“自定义标签”—— 定义组件的行使方法

“可相互结合”—— 组件正在有力的地点,组件间组装整合

“接口标准化”—— 组件接口有联合典型,或许是生命周期的管制

村办感到,模板技艺是基础力量,跟是还是不是组件化未有强联系,所以未有提议三个大点。

既然如此是进行,现阶段WebComponent的协助度还不成熟,不可能作为方案的花招。而除此以外一套以高品质设想Dom为切入点的组件框架React,在facebook的造势下,社区得到了大力发展。其他一名骨干Webpack,担任消除组件财富内聚,同有的时候间跟React极其相符产生补充。

所以【Webpack】+【React】将会是这套方案的大旨技巧。

不知情你今后是“又是react+webpack”以为失望manbetx2.0手机版 6,依然“太好了是react+webpack”不用再学三次新框架的喜悦manbetx2.0手机版 7。无论怎样上边包车型大巴剧情不会让您失望的。

一,组件生命周期

manbetx2.0手机版 8

React天生正是强制性组件化的,所以能够从根特性上化解面向进度代码所带来的辛苦。React组件自个儿有生命周期方法,能够满意“接口标准化”本领点。况且跟“页面结构模块化”的所封装抽离的多少个点子能挨个对应。另外react的jsx自带模板成效,把html页面片直接写在render方法内,组件内聚性越发严密。

鉴于React编写的JSX是会先生成设想Dom的,必要时机才真正插入到Dom树。使用React必得求通晓组件的生命周期,其生命周期多少个状态:

Mount: 插入Dom

Update: 更新Dom

Unmount: 拔出Dom

mount那单词翻译增添,嵌入等。我倒是提议“插入”更加好精通。插入!拔出!插入!拔出!默念二回,懂了没?别少看黄段子的力量,

manbetx2.0手机版 9

零件状态正是: 插入-> 更新 ->拔出。

然后各种组件状态会有二种管理函数,一前一后,will函数和did函数。

componentWillMount()  希图插入前

componentDidlMount()  插入后

componentWillUpdate() 企图更新前

componentDidUpdate()  更新后

componentWillUnmount() 计划拔出前

因为拔出后基本都以贤者形态(小编说的是组件),所以未有DidUnmount那么些方法。

别的React别的壹在这之中坚:数据模型props和state,对应着也许有自个状态方法

getInitialState()     获取最初化state。

getDefaultProps() 获取暗中认可props。对于那么些尚未父组件传递的props,通过该措施设置暗许的props

componentWillReceiveProps()  已插入的机件收到新的props时调用

再有三个特种境况的管理函数,用于优化管理

shouldComponentUpdate():判别组件是或不是供给update调用

增添最根本的render方法,React本身带的办法刚刚好12个。对于初学者的话是比较麻烦消化吸取。但事实上getInitialStatecomponentDidMountrender八个情况方法都能实现一大半零件,不必惧怕。

回来组件化的主旨。

一个页面结构模块化的零部件,能独立包装整个组件的进程线

manbetx2.0手机版 10

我们换算成React生命周期方法:

manbetx2.0手机版 11

 

组件的意况方法流中,有两点必要非常表明:

1,一遍渲染:

由于React的设想Dom本性,组件的render函数不需自身触发,依据props和state的转移自个通过差距算法,得出最优的渲染。

呼吁CGI常常都以异步,所以无可争辩带来叁遍渲染。只是空数据渲染的时候,有一点都不小希望会被React优化掉。当数码回来,通过setState,触发二遍render

 

2,componentWiillMount与componentDidMount的差别

和大多数React的课程小说分裂样,ajax央求小编建议在WillMount的章程内执行,并不是组件初步化成功现在的DidMount。那样能在“空数据渲染”阶段此前须求数据,尽早地减小二次渲染的岁月。

willMount只会执行二次,非常符合做init的业务。

didMount也只会执行贰次,而且那时候真实的Dom已经形成,特别切合事件绑定和complete类的逻辑。

 

 二,JSX极丑,可是组件内聚的重中之重!

WebComponents的标准之一,必要模板本事。本是认为是大家耳濡目染的沙盘本事,但React中的JSX这样的奇人照旧令人七嘴八舌。React还从未火起来的时候,大家就曾在微博上尖锐地嗤笑了“JSX写的代码那TM的丑”。那其实只是德姆o阶段JSX,等到实战的大型项目中的JSX,蕴涵多处境多数据多事件的时候,你会意识………….JSX写的代码仍旧很难看。

manbetx2.0手机版 12
(固然用sublime-babel等插件高亮,逻辑和渲染耦合一齐,阅读性照旧略差)

怎么大家会认为丑?因为大家曾经经对“视图-样式-逻辑”分离的做法耳闻则诵。

听他们说维护性和可读性,以致质量,大家都不建议直接在Dom下边绑定事件依然直接写style属性。我们会在JS写事件代理,在CSS上写上classname,html上的正是清晰的Dom结构。大家很好地爱抚着MVC的设计方式,一切平安。直到JSX把她们都夹杂在同步,所守护的技能栈受到侵袭,难免有着抗拒。

 

只是从组件化的目标来看,这种高内聚的做法未尝不可。

上面包车型大巴代码,在此以前的“逻辑视图分离”形式,咱们必要去找相应的js文件,相应的event函数体内,找到td-info的class所绑定的平地风波。

比较起JSX的可观内聚,所有的事件逻辑就是在自身jsx文件内,绑定的就是作者的showInfo方法。组件化的特征能立刻显示出来。

(注意:即便写法上大家好疑似HTML的内联事件管理器,不过在React底层并未实际赋值类似onClick属性,内层依旧采用类似事件代理的秘籍,高效地爱惜着事件管理器)

再来看一段style的jsx。其实jsx未有对体制有硬性规定,大家完全可服从此前的定义class的逻辑。任何一段样式都应当用class来定义。在jsx你也全然能够如此做。但是由于组件的独立性,小编建议部分独有“一回性”的样式直接选择style赋值更加好。收缩冗余的class。

XHTML

<div className=”list” style={{background: “#ddd”}}> {list_html}
</div>

1
2
3
<div className="list" style={{background: "#ddd"}}>
   {list_html}
</div>

大概JSX内部有担任繁琐的逻辑样式,可JSX的自定义标签手艺,组件的黑盒性立马能感受出来,是或不是弹指间美好了数不尽。

JavaScript

render: function(){ return ( <div> <Menus
bannerNums={this.state.list.length}></Menus> <TableList
data={this.state.list}></TableList> </div> ); }

1
2
3
4
5
6
7
8
render: function(){
    return (
      <div>
         <Menus bannerNums={this.state.list.length}></Menus>
         <TableList data={this.state.list}></TableList>
      </div>
   );
}

就算如此JSX本质上是为了虚构Dom而希图的,但这种逻辑和视图中度合一对于组件化未尝不是一件好事。

 

学习完React那么些组件化框架后,看看组件化技巧点的成就景况

“财富高内聚”—— (33%)  html与js内聚

“功能域独立”—— (四分之二)  js的效用域独立

“自定义标签”—— (百分百)jsx

“可相互结合”—— (百分之五十)  可整合,但紧缺有效的加载情势

“接口标准化”—— (百分百)组件生命周期方法

 

Webpack 能源组件化

对此组件化的财富独立性,常常的模块加载工具和创设流程视乎变得劳碌。组件化的营造筑工程程化,不再是在此之前大家遍布的,css合二,js合三,而是体验在组件间的借助于加载关系。webpack正好合乎要求点,一方面填补组件化手艺点,另一方支持大家健全组件化的完好构建境遇。

第一要表惠氏(WYETH)点是,webpack是一个模块加载打包工具,用于管理你的模块财富正视打包难题。那跟我们熟识的requirejs模块加载工具,和grunt/gulp营造筑工程具的概念,多多少少有些出入又有个别雷同。

manbetx2.0手机版 13

率先webpak对于CommonJS与AMD同一时间援救,满足大家模块/组件的加载方式。

JavaScript

require(“module”); require(“../file.js”); exports.doStuff = function()
{}; module.exports = someValue;

1
2
3
4
require("module");
require("../file.js");
exports.doStuff = function() {};
module.exports = someValue;

JavaScript

define(“mymodule”, [“dep1”, “dep2”], function(d1, d2) { return
someExportedValue; });

1
2
3
define("mymodule", ["dep1", "dep2"], function(d1, d2) {
    return someExportedValue;
});

本来最精锐的,最非凡的,当然是模块打包功能。那就是这一功力,补充了组件化能源注重,以及完整工程化的力量

基于webpack的安排意见,全体财富都以“模块”,webpack内部贯彻了一套财富加运载飞机制,能够把想css,图片等财富等有依附关系的“模块”加载。那跟大家选择requirejs这种唯有管理js大大不一致。而那套加运载飞机制,通过多个个loader来达成。

 

JavaScript

// webpack.config.js module.exports = { entry: { entry: ‘./index.jsx’,
}, output: { path: __dirname, filename: ‘[name].min.js’ }, module:
{ loaders: [ {test: /\.css$/, loader: ‘style!css’ }, {test:
/\.(jsx|js)?$/, loader: ‘jsx?harmony’, exclude: /node_modules/},
{test: /\.(png|jpg|jpeg)$/, loader: ‘url-loader?limit=10240’} ] } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// webpack.config.js
module.exports = {
    entry: {
     entry: ‘./index.jsx’,
    },
    output: {
        path: __dirname,
        filename: ‘[name].min.js’
    },
    module: {
        loaders: [
            {test: /\.css$/, loader: ‘style!css’ },
            {test: /\.(jsx|js)?$/, loader: ‘jsx?harmony’, exclude: /node_modules/},
            {test: /\.(png|jpg|jpeg)$/, loader: ‘url-loader?limit=10240’}
        ]
    }
};

下面一份简单的webpack配置文件,在意loaders的安顿,数组内一个object配置为一种模块能源的加运载飞机制。test的正则为同盟文件法则,loader的为相称到文件将由哪些加载器管理,七个Computer之间用相隔,管理顺序从右到左。

 

style!css,css文件通过css-loader(管理css),再到style-loader(inline到html)的加工管理流。

jsx文件通过jsx-loader编写翻译,‘?’开启加载参数,harmony帮助ES6的语法。

图形能源通过url-loader加载器,配置参数limit,调整少于10KB的图片将会base64化。

 财富文件怎么着被require?

JavaScript

// 加载组件自己css require(‘./slider.css’); // 加载组件信任的模块 var
Clip = require(‘./clipitem.js’); // 加载图片能源 var spinnerImg =
require(‘./loading.png’);

1
2
3
4
5
6
// 加载组件自身css
require(‘./slider.css’);
// 加载组件依赖的模块
var Clip = require(‘./clipitem.js’);
// 加载图片资源
var spinnerImg = require(‘./loading.png’);

在webpack的js文件中我们除了require大家例行的js文件,css和png等静态文件也足以被require进来。大家经过webpack命令,编译之后,看看输出结果什么:

JavaScript

webpackJsonp([0], { /* 0 */ /***/ function(module, exports,
__webpack_require__) { // 加载组件自个儿css
__webpack_require__(1); // 加载组件正视的模块 var Clip =
__webpack_require__(5); // 加载图片能源 var spinnerImg =
__webpack_require__(6); /***/ }, /* 1 */ /***/
function(module, exports, __webpack_require__) { /***/ }, /* 2
*/ /***/ function(module, exports, __webpack_require__) {
exports = module.exports = __webpack_require__(3)();
exports.push([module.id, “.slider-wrap{\r\n position: relative;\r\n
width: 100%;\r\n margin: 50px;\r\n background:
#fff;\r\n}\r\n\r\n.slider-wrap li{\r\n text-align:
center;\r\n line-height: 20px;\r\n}”, “”]); /***/ }, /* 3 */
/***/ function(module, exports) { /***/ }, /* 4 */ /***/
function(module, exports, __webpack_require__) { /***/ }, /* 5
*/ /***/ function(module, exports) { console.log(‘hello, here is
clipitem.js’) ; /***/ }, /* 6 */ /***/ function(module, exports)
{ module.exports = “data:image/png;base64,iVBORw0KGg……” /***/ }
]);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
webpackJsonp([0], {
/* 0 */
/***/ function(module, exports, __webpack_require__) {
          // 加载组件自身css
          __webpack_require__(1);
          // 加载组件依赖的模块
          var Clip = __webpack_require__(5);
          // 加载图片资源
          var spinnerImg = __webpack_require__(6);
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
 
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
          exports = module.exports = __webpack_require__(3)();
          exports.push([module.id, ".slider-wrap{\r\n position: relative;\r\n width: 100%;\r\n margin: 50px;\r\n background: #fff;\r\n}\r\n\r\n.slider-wrap li{\r\n text-align: center;\r\n line-height: 20px;\r\n}", ""]);
 
/***/ },
/* 3 */
/***/ function(module, exports) {
 
/***/ },
 
/* 4 */
/***/ function(module, exports, __webpack_require__) {
/***/ },
 
/* 5 */
/***/ function(module, exports) {
          console.log(‘hello, here is clipitem.js’) ;
/***/ },
/* 6 */
/***/ function(module, exports) {
          module.exports = "data:image/png;base64,iVBORw0KGg……"
/***/ }
]);

webpack编写翻译之后,输出文件视乎乱糟糟的,但实在每二个能源都被封装在多个函数体内,而且以编号的格局标识(注释)。这几个模块,由webpack的__webpack_require__内部方法加载。入口文件为编号0的函数index.js,能够见见__webpack_require__加载别的编号的模块。

css文件在号码1,由于应用css-loader和style-loader,编号1-4都以拍卖css。个中编号2大家得以看大家的css的string体。最后会以内联的法子插入到html中。

图表文件在号码6,可以看出exports出base64化的图纸。

 组件一体输出

JavaScript

// 加载组件本人css require(‘./slider.css’); // 加载组件依赖的模块 var
React = require(‘react’); var Clip = require(‘../ui/clipitem.jsx’); //
加载图片能源 var spinnerImg = require(‘./loading.png’); var Slider =
React.createClass({ getInitialState: function() { // … },
componentDidMount: function(){ // … }, render: function() { return (
<div> <Clip data={this.props.imgs} /> <img
className=”loading” src={spinnerImg} /> </div> ); } });
module.exports = Slider;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 加载组件自身css
require(‘./slider.css’);
// 加载组件依赖的模块
var React = require(‘react’);
var Clip = require(‘../ui/clipitem.jsx’);
// 加载图片资源
var spinnerImg = require(‘./loading.png’);
var Slider = React.createClass({
    getInitialState: function() {
        // …
    },
    componentDidMount: function(){
        // …
    },
    render: function() {
        return (
            <div>
               <Clip data={this.props.imgs} />
               <img className="loading" src={spinnerImg} />
            </div>
        );
    }
});
module.exports = Slider;

如若说,react使到html和js合为紧密。

那正是说丰硕webpack,两个结合一同的话。js,css,png(base64),html
全数web能源都能合成三个JS文件。那多亏那套方案的主干所在:组件独立一体化。要是要援用多少个组件,仅仅require('./slider.js') 就能够完结。

 

步向webpack的模块加载器之后,大家组件的加载难题,内聚难点也都工作有成地消除掉

“能源高内聚”—— (百分之百) 全部能源得以一js出口

“可交互结合”—— (百分之百)  可结合可依赖加载

 

 CSS模块化实施

很惊喜,你能读书到这里。如今我们的机件实现度特别的高,财富内聚,易于组合,功能域独立互不污染。。。。等等manbetx2.0手机版 14,视乎CSS模块的实现度有欠缺。

那么前段时间组件达成度来看,CSS效能域其实是全局性的,并不是组件内部独立。下一步,大家要做得正是怎样让大家组件内部的CSS功用域独立。

那时候只怕有人立时跳出,大喊一句“德玛西亚!”,哦不,应该是“用sass啊傻逼!”。不过种类组件化之后,组件的中间封装已经很好了,其里面dom结交涉css趋向轻松,独立,以致是破破烂烂的。LESS和SASS的一体式样式框架的宏图,他的嵌套,变量,include,函数等丰富的效能对于全体大型项目标样式处理十二分有效。但对此三个成效单一组件内部样式,视乎就变的略微抵触。“无法为了框架而框架,合适才是最棒的”。视乎原生的css本领已经知足组件的体裁要求,唯独就是地方的css功能域难点。

 

此地自身付诸思虑的方案:
classname随意写,保持原生的艺术。编写翻译阶段,依据组件在档期的顺序路径的独一性,由【组件classname+组件独一门路】打成md5,生成全局独一性classname。正当自家要写多少个loader实现自己的主见的时候,开采歪果仁已经早在先走一步了。。。。

那边具体方案仿照效法小编前面博客的译文:http://www.alloyteam.com/2015/10/8536/

事先大家谈谈过JS的模块。今后由此Webpack被加载的CSS资源叫做“CSS模块”?笔者感觉还是有毛病的。未来style-loader插件的贯彻精神上只是创建link[rel=stylesheet]要素插入到document中。这种行为和平凡引进JS模块极度例外。引进另一个JS模块是调用它所提供的接口,但引进三个CSS却并不“调用”CSS。所以引进CSS本人对于JS程序来讲并不设有“模块化”意义,纯粹只是表达了一种财富信赖——即该器件所要完结的功效还须要或多或少asset。

于是,那位歪果仁还扩展了“CSS模块化”的定义,除了上边的大家供给有个别成效域外,还会有不菲意义,这里不详述。具体仿照效法原著 http://glenmaddern.com/articles/css-modules

不行赞的一些,正是cssmodules已经被css-loader收纳。所以大家没有须求依赖额外的loader,基本的css-loader开启参数modules就可以

JavaScript

//webpack.config.js … module: { loaders: [ {test: /\.css$/, loader:
‘style!css?modules&localIdentName=[local]__[name]_[hash:base64:5]’
}, ] } ….

1
2
3
4
5
6
7
8
//webpack.config.js
…  
    module: {
        loaders: [
            {test: /\.css$/, loader: ‘style!css?modules&localIdentName=[local]__[name]_[hash:base64:5]’ },
        ]  
    }
….

modules参数代表开启css-modules功效,loaclIdentName为设置我们编译后的css名字,为了便于debug,大家把classname(local)和零部件名字(name)输出。当然能够在结尾输出的版本为了节约提交,仅仅使用hash值就能够。其它在react中的用法大约如下。

JavaScript

var styles = require(‘./banner.css’); var Banner = new
React.createClass({ … render: function(){ return ( <div> <div
className={styles.classA}></div> </div> ) } });

1
2
3
4
5
6
7
8
9
10
11
var styles = require(‘./banner.css’);
var Banner = new React.createClass({
    …
    render: function(){
        return (
            <div>
                <div className={styles.classA}></div>
            </div>
        )
    }
});

最后这里关于出于对CSS一些研商,

至于css-modules的其他功效,作者并不筹划选拔。在个中分享【大家竭尽所能地让CSS变得复杂】中谈到:

咱俩项目中相当多的CSS都不会像boostrap这样须要变量来安装,身为一线开采者的我们大约能够感受到:设计师们改版UI,相对不是轻便的换个色或改个间距,而是万物更新的全新UI,那纯属不是贰个变量所能消除的”维护性“。

反倒项目实战进度中,真正要消除的是:在本子迭代进程中那三个淘汰掉的过期CSS,大批量地积聚在项目当中。大家像极了家中的欧巴酱不舍得甩掉没用的事物,因为那只是我们应用sass或less编写出具备莫斯中国科学技术大学学的可维护性的,断定有复用的一天。

那些堆叠的逾期CSS(or
sass)之间又有局地注重,一部分超时失效了,一部分又被新的体裁复用了,导致没人敢动这几个历史样式。结果现网项目迭代还带着多量四年前没用的体裁文件。

组件化之后,css的布局同样被退换了。或然postcss才是你以往手上最切合的工具,而不在是sass。

 

到此处,大家算是把组件化最终一个标题也消除了。

“效能域独立”—— (百分百) 就像shadowDom功用域独立

 

到此地,大家可以开一瓶82年的Sprite,好好庆祝一下。不是啊?

manbetx2.0手机版 15

 

 组件化之路还在此伏彼起

webpack和react还有大多新特别关键的本性和效益,介于本文仅仅围绕着组件化的为骨干,没有各样阐述。其余,配搭gulp/grunt补充webpack营造本领,webpack的codeSplitting,react的组件通讯难题,开拓与生产条件安插等等,都以整个大型项目方案的所不可不的,限于篇幅问题。能够等等笔者更新下篇,或大家可以活动查阅。

而是,不得不再安利一下react-hotloader神器。热加载的付出格局相对是下一代前端开垦必备。严峻说,万一未有了热加载,作者会很坚决地舍弃这套方案,即便那套方案再怎么能够,小编都讨厌react供给5~6s的编写翻译时间。可是hotloader能够在自个儿不刷新页面包车型大巴图景下,动态修改代码,並且不单单是样式,连逻辑也是即时生效。

manbetx2.0手机版 16

如上在form表单内。使用热加载,表单不供给再一次填写,修改submit的逻辑立即见效。那样的开支作用真不是拉长仅仅几个水平。必需安利一下。

 

只怕你意识,使用组件化方案现在,整个才具栈都被更新了一番。学习成本也不菲,而且能够预言到,基于组件化的前端还大概会过多欠缺的主题素材,比方品质优化方案须要重新思虑,以至最宗旨的零部件可复用性不肯定高。前边不长一段时间,必要大家不断磨炼与优化,研究最优的前端组件化之道。

足足咱们能够想像,不再忧虑本人写的代码跟某些什么人什么人争持,不再为找某段逻辑在多个文本和艺术间持续,不再copy一片片逻辑然后改改。大家每便编写都是可选择,可结合,独立且内聚的零件。而各样页面将会由三个个嵌套组合的组件,相互独立却相互功能。

 

对此那样的前端今后,有所指望,不是很好啊

从那之后,谢谢您的读书。

1 赞 6 收藏 1
评论

manbetx2.0手机版 17

HTML导入

咱俩长日子之前就能够导入JavaScript和CSS了。 HTML导入功用提供了从别的HTML文书档案中程导弹入和重用HTML文书档案的才具。这种简单性同期表示能够很有益地用有个别组件创设另一对零部件。

末段,那样的格式很优异,切合可接纳组件,何况能够用你最兴奋的包管理技术方案发布(比如: bower、 npm 或者 Component)。

X-Tag和Brick

Mozilla开荒了和睦的自定义成分包容库,叫做 X-Tag。X-Tag是三个为启用Web
Component实行多项宽容的库,并将在提供对Web Component的完好协理。

以下正是行使X-Tag的 my-avatar 自定义组件,与正规文档相当近乎:

查阅代码演示:http://jsbin.com/wexiz/2/edit

Mozilla同临时候还创设了贰个叫 Brick 的库,当中包罗X-Tag,提供“一组用来便于急忙营造Web应用程序的UI组件”,使用与谷歌(Google)的Polymer相似的章程。

可互换

二个意义显明好组件的API能令人私行地改成其内部的效果达成。要是程序内部的组件是松耦合的,那实在能够用贰个组件轻松地更迭另三个零部件,只要遵从毫发不爽的 API/接口/约定

比方你选取GoInstant提供的实时功用劳动组件,这她们下周闭馆服务这么的新闻会影响到您。然则,只要提供了一模一样的数码同步API,你也能够自动创设利用三个 FirebaseComponent 组件可能 PubNubComponent 组件。

总结

动用基于组件的架构营造应用程序有那多少个益处,你能从现存的框架中学到,也能在创设前端Web应用程序时从引进的Web
Component中上学到。

本场组件化Web王国的旅程,让我们在面对框架和工具的选项时意马心猿不决。然而,Web
Component会是终极的点灯!

Web
Component会提供营造应用程序的原生统一的办法。现成的框架很有不小希望会转而利用Web
Component或许表明什么与它一起使用。Ember的国策是让迁移到Web
Component越发有益,而Facebook的React则是自己要作为榜样服从规则整合的好例子,已经有四个 ReactiveElements示范它了。因为Angular和Polymer都以谷歌的门类,他们很有希望会走到四只。

如何是组件?

软件开拓是二个语义丰裕(术语常常持续贰个情趣)的领域。很令人瞩目,这里的“组件”是一个很泛的称为,所以有要求指明我们想要表达的,在前面三个Web应用的言语情形中的意思。

前端Web应用中的组件,是指部分统一准备为通用性的,用来构建相当的大型应用程序的软件,那么些组件有各个表现形式。它能够是有UI(顾客分界面)的,也足以是用作
“服务”的纯逻辑代码。

因为有视觉上的表现格局,UI组件更易于精通。UI组件简单的例证富含开关、输入框和文本域。不论是慕尼黑包状的菜单开关(无论你是不是喜欢)、标签页、日历、选项菜单或许所见即所得的富文本编辑器则是一些尤为高等的事例。

提供服务类型的零部件或然会令人为难理解,那类别型的例子富含跨浏览器的AJAX支持,日志记录或许提供某种数据持久化的法力。

据书上说组件开荒,最重大的正是组件能够用来组合任何零件,而富文本编辑器正是个很好的例子。它是由开关、下拉菜单和有个别可视化组件等组合。另贰个例证是HTML5上的video成分。它同样包含按键,也同期富含贰个能从录制数据流渲染内容的要素。

Ember

框架与库的争论旷日漫长,总的来讲框架是挟持你按某种格局做专门的学问,所以它是穷凶极恶的。很扎眼,Angular是个框架,而Ember的撰稿人,Yehuda
Katz和汤姆Dale也很乐于把Ember看作框架

Ember 有对它叫做组件的内建支持。Ember
Components背后的见解是尽恐怕的向Web
Components看齐,当浏览器匡助允许时,就能够很有益于地搬迁到Web
Components中。

翻开代码演示: http://jsbin.com/nawuwi/4/edit

地点的例子中使用了 handlebars 做模板,所以元素的概念不是平等种语法。

内容提要

应用过多单独组件创设应用程序的主张并不出色。Web
Component的面世,是重复记念基于组件的应用程序开垦方式的好机缘。大家能够从那几个进度中收益,掌握什么使用现存技巧产生目的,而且在以往做出本人的前端Web应用。
 

Shadow DOM

还记得iframe们吧?大家还在运用它们,是因为他们能确认保证组件和控件的JavaScript和CSS不会潜濡默化页面。 Shadow
DOM
 也能提供这么的维护,并且未有iframe带来的担当。正式的说教是:

Shadow
DOM的统一筹算是在shadow根下隐敝DOM子树进而提供包装机制。它提供了树立和保全DOM树之间的功能界限,以及给这个树提供相互的功效,进而在DOM树上提供了越来越好的功能封装。

自定义成分

作者们在上边关怀的是用Angular、Ember和React创设 my-avatar 的例证。大概的场馆下,那样的艺术将以页面上或许模板上丰裕的自定义成分表示。Web
Component满含经过自定义成分收获的原生补助– 相对是Web Component标准的宗旨组成都部队分。

概念新成分,包罗拜见成分生命周期的一对事件举个例子什么时候创立(createdCallback)、哪天加多在DOM树上(attachedCallback)、几时从DOM树上分离(detachedCallback),哪一天成分属性改换(attributeChangedCallback(attrName, oldVal, newVal))。

自定义元素的三个主要的部分正是有力量从原来成分扩大,由此获得原有元素相应的功用。示例中大家扩展了 <img>元素 。

末了,大家所写的代码中,自定义元素正在并且侧向去做的就是将复杂的事物抽象化,让客商关怀于单个组件产生的市场总值,进而用来创设尤其丰硕的功能。

何以要营造组件?

既然如此未来曾经领悟组件的情致,就看看使用组件的办法营造前端接纳的低价。

可组合

之前也钻探过,基于组件的架构让组件组合成新组件尤其轻巧。那样的统一准备让组件尤其专一,也让任何零件中营造和揭露的坚守更加好利用。

不论是给程序增多效果,照旧用来制作完整的次第,特别眼花缭乱的法力也能生搬硬套。那正是这种措施的尤为重要利润。

是或不是有须求把具有的东西调换到组件,事实上决定于你和谐。未有任何理由让你的程序由 你自己 的零部件组合成你最惊叹的功能 ,乃至 最花哨的功能。而这几个零件又扭曲构成任何零件。假诺你从那几个主意中收获了利润,就想尽地去百折不挠它。不过要小心的是,不要用同一的格局把事情变得复杂,你并无需过分关心如何让组件重用。而是要关切展现程序的成效。

React

React 固然是个新人,不过却早已有为数不菲的拥护者。它由推文(Tweet)(TWT奥德赛.US)开采,何况一度到家用于推特(Twitter)的UI和局地脸谱的UI。

选用React营造组件的推荐介绍方式是行使叫做 JSX 的东西来定义它们。那是一种“推荐在React上选取的JavaScript语法转变”。请不要为此分心。他们早就在文书档案中提出,这一个主见便是用来援助您在JavaScript中写出HTML标识的。

自己不是说你并不得以一直在HTML中增多标签,而必得使用JSX创设和煦的组件。可是,只要您定义了贰个零部件,你就足以选拔那几个组件成立别的零件。

翻开代码演示: http://jsbin.com/qigoz/5/edit

所以,组件使用的证明语法需求相应的HTML成分和对 React.RenderComponent 的调用。

高内聚

又是贰个软件工程的高频词! 我们将有关的一些效果公司在一同,把任何封装起来,而在组件的事例中,就大概是相关的效果逻辑和静态能源:JavaScript、HTML、CSS以及图像等。那正是咱们所说的内聚。

这种做法将让组件更便于保障,何况这么做之后,组件的可相信性也将增长。同临时候,它也能让组件的功能鲜明,增大组件重用的大概性。

表面能源(瑞典语)

 

Platform.js

可是,就像每一回提到新特征一样,大家不能够明确浏览器是还是不是辅助这么些特色。

manbetx2.0手机版 18

截至二〇一五年八月十七日,Web Component 的浏览器扶助意况

平等,大家也能由此一些奇妙的同盟代码,起初选用一些Web
Component所提供的成效。

manbetx2.0手机版 19

有了宽容库的Web Component扶助景况

好新闻是多少个最早进的浏览器厂家Google和Mozilla正在大力健全宽容库
,扶助大家运用Web Component。

以下示例呈现使用platform.js后我们可以怎么定义作为img成分扩大的my-avatar成分。最好的是它能用到原生img成分的享有功用。

翻开代码演示: http://jsbin.com/pihuz/4/edit

点击 HTML5 Rocks Custom Elements
tutorial
 以查看成立自定义成分的更多音讯。

注:要是你对platform.js感兴趣,也得以看看 bosonic

原生手艺的帮衬目标正是给大家提供对应的创设基础。所以Web
Component而不是库和框架的晚期时限信号。

Polymer

Polymer 是演示创设基于原生Web
Component作用的顶级示例。它提供了增选的机制用来创设自定义的Polymer成分,并且提供了广大中坚的UI组件,让您能够创制和谐的应用程序。

manbetx2.0手机版 20

上边你能够见到 my-avatar 成分的简约创制进度,同一时候我们也赢得了想要的号子。

翻开代码演示: http://jsbin.com/gukoku/2/edit

Google正在拼命拉动Polymer。请查看 Polymer getting started
guide
 查看越来越多示例。

未来:Web Component和其他

Web
Component才是前景!正如名字所表示的那么,他们承诺将推动能够将成效封装成组件的浏览器原生扶助。

自身将简单体现Web
Component并且演示大家未来得以什么选择它。尤其长远的原委请参见本文末尾的 “外界能源” 一节。

她们提供的功效包蕴:

组件间是什么样通讯的?

在深深示例在此之前有不可或缺简单地关系组件间通讯的主题素材。假若组件之间是“独立”、“模块化”的,他们又是何许相互通讯的吧?

最明显的答案就是让组件间互相援用并经过她们之间的API交互。那样做的标题就在于,这种做法会让组件相互信任。长时间内只怕幸亏,一段时间今后,你在修改程序的时候程序会失控,修改一个组件就能对另四个组件产生异常的大的震慑。决定移除叁个无法推动预期价值组件也许会让您的应用程序甘休工作,因为它背后会有数个零件信赖于它。

此时,实施方案是提供松耦合的,让组件之间比较少依旧大约不驾驭互相的方案。组件并不直接创立其余零件,在他们要求通讯的时候,他们经过“接口/约定”可能通过 “服务”。大家在营造BQX56JS程序时思量了广大那几个地点的事物,何况使用 ServiceRegistry 访谈用于组件间通信的劳务还是是Web
API
这么的能源。Angular和Ember采取了服务和借助注入杀鸡取卵那类难点。

模块

您或许听别人讲过 “组件是天生模块”的说法。好呢,多谢它,大家又要分解这里的术语!

你恐怕会认为“组件”的传道更为相符用来陈诉UI,而“模块”更切合描述提供服务的效果与利益逻辑。而对此小编来讲,模块和零部件意思周围,都提供团体、聚集和包裹,是与某些意义单位有关的。

可重用

您看看的示范组件,越发是Web
Component,更关怀可选择的标题。功效显然,完毕清晰,API易于精通。自然就能够推进组件复用。通过营造可选拔组件,大家不但保障了 DRubiconY(不要再一次造轮子)条件,还赢得了对应的裨益。

这里要提醒: 不要过度尝试营造可接纳组件。你更应有关爱应用程序上所急需的那多个特定部分。若是未来相应供给出现,恐怕零部件的确到了可选取的地步,就花一点十一分时间让组件重用。事实上,开荒者都爱好去创设可选拔成效块(库、组件、模块、插件等),做得太早将会让您后来难受不堪。所以,吸收基于组件开拓的别的受益,何况接受不是装有组件都能重用的真相。

演示组件my-avatar

为了体现我们什么用这么些库和框架塑造最宗旨的组件,我们创制了一个暗含UI,用于取回和出示客户头像的粗略示例。在大概的情况下,该器件会有 my-avatar 标签,会从以下五个个性中拿走头像:

模板

大家中的许五人早已选择像handlebars、mustache只怕underscore.js中的模板那样的缓慢解决方案(就疑似我们在地方的Ember示例中用的一样)。Web
Component通过 template元素 提供了模版的原生扶助

原生模板让您能够注解分类为“隐敝DOM”然而深入分析成HTML的暗记片段。他们在页面加载时未尝用处,不过足以在运作时实例化。他们能够被寻觅到 ,然则在插入活动的DOM树前不会加载任何有关能源。

AngularJS

AngularJS 恐怕是前些天用于塑造程序最风靡的前端建设方案了。作为创我的谷歌(Google),重新思虑HTML,考虑什么重新发明,满足前段时间Web开拓的内需。

Angular中得以动用自定义指令概念组件。之后,你能够利用 HTML
标志评释自定义组件。

查看代码演示: http://jsbin.com/lacog/2/edit

本条例子呈现了使用Angular指令的简便程度。值scope 定义了从
 my-avatar 成分中收获,并且之后用来创设相应的img标签和渲染成客商头像的品质。

方今就从头创设组件

在 Caplin
Systems
 创设基于组件的自有应用程序时,作者动用了几条原则和实行。这一个准绳由 BladeRunnerJS(BRJS) 开源工具集支撑。它被称作”BladeRunnerJS”
是因为大家将顺序作用都封装在称作 Blades 的事物中。Blade是能够在某些应用中收录的机能特色,不过不得以在程序间重用。当作用真的
变得更其通用的时候,大家将相应的定义移到库文件中,供各类程序间使用。特定应用中的组件(blade)和我们先后间的通用组件能够运用,大家如若找到最棒满足急需的任何库和框架。

那么,现在什么库和框架能够协助我们创设组件呢?

在支配营造利用时应利用何种能力时,只要求探视流行的 TodoMVC 网址就能够知到大量可供选取的前端库和框架。你大概会以为任何一种方案都能用来创设基于组件的应用程序。可是,他们中间的一部分方案内置了对组件的支撑。个中相比较著名的是AngularJS、Ember
和 React。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图