编者按:作者高凯从JS的中古时代的jQuery说起,到Backbone,再到Augular,最后到现代的时髦的React,为我们梳理了WebComponent从概念到标准化的历程
援引MDN上的解释:
WebComponentsconsistsofseveralseparatetechnologies.YoucanthinkofWebComponentsasreusableuserinterfacewidgetsthatarecreatedusingopenWebtechnology.TheyarepartofthebrowserandsotheydonotneedexternallibrarieslikejQueryorDojo.AnexistingWebComponentcanbeusedwithoutwritingcode,simplybyaddinganimportstatementtoanHTMLpage.WebComponentsuseneworstill-developingstandardbrowsercapabilities.
简单的讲,WebComponent就是把组件封装成html标签的形式,并且在使用时不需要写额外的js代码。
假设需要一段代码把几个色块染色。在jq时代,我们会从这样的代码开始:
$('.div1').html('redlight').css({background:'red'});$('.div2').html('yellowlight').css({background:'yellow'});$('.div3').html('greenlight').css({background:'green'});完全过程式的代码。在稍微复杂的情况下,可以进行抽象,封装成Light类:
functionLight(el,color){this.el=el;this.color=color;}Light.prototype={render:function(){this.el.css({background:this.color})}};varredLight=newLight($('.div1'),'red');varyellowLight=newLight($('.div2'),'yellow');vargreenLight=newLight($('.div3'),'green');varins=[redLight,yellowLight,greenLight];ins.forEach(function(item){item.render();});面对对象之后,我们可以复用代码了。并且在维护性上也得到了些微的提升。我们可以继承这个类,加上更多的接口和展现形态:
functionLight(el,color){this.el=el;this.color=color;}Light.prototype={render:function(){this.el.css({background:this.color})}};functionCircleLight(){Light.apply(this,arguments);}CircleLight.prototype=Object.create(Light.prototype);$.extend(CircleLight.prototype,{render:function(){Light.prototype.render.apply(this,arguments);this.el.css({width:50,height:50,borderRadius:'50%'});}});varins=[];$('.div1,.div2,.div3').each(function(){varelem=$(this);varklass=Light;if(elem.hasClass('circle')){klass=CircleLight;}ins.push(newklass(elem,elem.data('color')));});ins.forEach(function(item){item.render();});CircleLight类继承自Light。重写了render接口,加上圆形的效果。在实例渲染时调用并不需要区别两种类,只调用render即可,这样在扩展基类时会变得非常方便。
在此之上再引入mvc的概念,前端发明了Backbone框架。
还是刚才的例子,但是这次把数据和渲染层分开,于是就有了:
varLightModel=Backbone.Model.extend({defaults:{color:'red'}});varLightCollection=Backbone.Collection.extend({model:LightModel});vartpl='
唯一的缺点就是累。如果要在Backbone里做局部刷新就更麻烦了,抽象更多的view或者在render中操作局部dom。而麻烦和累是程序的原罪。于是又过了几年,我们有了angular。
varapp=angular.module('lightApp',[]);app.controller('LightCtrl',function($scope){$scope.lights=['red','yellow','green'];$scope.add=function(){$scope.lights.push('blue');};});angular.bootstrap($('#ng-container')[0],['lightApp']);//html